ZQuest Classic Coverage Report


Directory: src/
File: src/zc/ffscript.cpp
Date: 2025-11-20 06:30:46
Exec Total Coverage
Lines: 6409 17151 37.4%
Functions: 441 660 66.8%
Branches: 3341 12663 26.4%

Line Branch Exec Source
1 #include <cstdint>
2 #include <deque>
3 #include <memory>
4 #include <string>
5 #include <sstream>
6 #include <math.h>
7 #include <cstdio>
8 #include <algorithm>
9 #include <ranges>
10 //
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <fstream>
16 #include <fmt/format.h>
17 #include <fmt/ranges.h>
18 //
19
20 #include "base/check.h"
21 #include "base/expected.h"
22 #include "base/handles.h"
23 #include "base/general.h"
24 #include "base/mapscr.h"
25 #include "base/qrs.h"
26 #include "base/dmap.h"
27 #include "base/msgstr.h"
28 #include "base/packfile.h"
29 #include "base/misctypes.h"
30 #include "base/initdata.h"
31 #include "base/scc.h"
32 #include "base/version.h"
33 #include "new_subscr.h"
34 #include "zc/maps.h"
35 #include "zasm/serialize.h"
36 #include "zasm/table.h"
37 #include "zc/replay.h"
38 #include "zc/scripting/array_manager.h"
39 #include "zc/scripting/arrays.h"
40 #include "zc/scripting/common.h"
41 #include "zc/scripting/script_object.h"
42 #include "zc/scripting/sram.h"
43 #include "zc/scripting/string_utils.h"
44 #include "zc/scripting/types.h"
45 #include "zc/scripting/types/directory.h"
46 #include "zc/scripting/types/file.h"
47 #include "zc/scripting/types/websocket.h"
48 #include "zc/zasm_optimize.h"
49 #include "zc/zasm_utils.h"
50 #include "zc/zc_ffc.h"
51 #include "zc/zc_sys.h"
52 #include "zc/jit.h"
53 #include "zc/script_debug.h"
54 #include "base/zc_alleg.h"
55 #include "base/zc_math.h"
56 #include "base/zc_array.h"
57 #include "zc/ffscript.h"
58 #include "zc/render.h"
59 #include "zc/zc_subscr.h"
60 #include <time.h>
61 #include "zc/script_drawing.h"
62 #include "base/util.h"
63 #include "zc/ending.h"
64 #include "zc/combos.h"
65 #include "drawing.h"
66 #include "base/colors.h"
67 #include "pal.h"
68 #include "zinfo.h"
69 #include "subscr.h"
70 #include "zc_list_data.h"
71 #include "music_playback.h"
72 #include "iter.h"
73 #include <sstream>
74
75 #include "zc/zelda.h"
76 #include "particles.h"
77 #include "zc/hero.h"
78 #include "zc/guys.h"
79 #include "gamedata.h"
80 #include "zc/zc_init.h"
81 #include "base/zsys.h"
82 #include "base/misctypes.h"
83 #include "zc/title.h"
84 #include "zscriptversion.h"
85
86 #include "pal.h"
87 #include "base/zdefs.h"
88 #include "zc/rendertarget.h"
89
90 #include "hero_tiles.h"
91 #include "base/qst.h"
92
93 using namespace util;
94
95 using namespace util;
96 using std::ostringstream;
97
98 static ASM_DEFINE current_zasm_command;
99 static uint32_t current_zasm_register;
100 // If set, the next call to scripting_log_error_with_context will use this string in addition to whatever
101 // current_zasm_command and current_zasm_register refer to. Must unset after manually.
102 std::string current_zasm_extra_context;
103 // If set, the next call to scripting_log_error_with_context will use this string instead of whatever
104 // current_zasm_command and current_zasm_register refer to. Must unset after manually.
105 std::string current_zasm_context;
106
107 2148216 void scripting_log_error_with_context(std::string text)
108 {
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2148216 times.
2148216 if (current_zasm_context.empty())
110 {
111 2148216 std::vector<const char*> context;
112
113
1/2
✓ Branch 0 taken 2148216 times.
✗ Branch 1 not taken.
2148216 const char* command_string = scripting_get_zasm_command_context_string(current_zasm_command);
114
2/2
✓ Branch 0 taken 387817 times.
✓ Branch 1 taken 1760399 times.
2148216 if (command_string)
115
1/2
✓ Branch 0 taken 387817 times.
✗ Branch 1 not taken.
387817 context.push_back(command_string);
116
117
1/2
✓ Branch 0 taken 2148216 times.
✗ Branch 1 not taken.
2148216 const char* register_string = scripting_get_zasm_register_context_string(current_zasm_register);
118
2/2
✓ Branch 0 taken 1005625 times.
✓ Branch 1 taken 1142591 times.
2148216 if (register_string)
119
1/2
✓ Branch 0 taken 1005625 times.
✗ Branch 1 not taken.
1005625 context.push_back(register_string);
120
121
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2148212 times.
2148216 if (!current_zasm_extra_context.empty())
122
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 context.push_back(current_zasm_extra_context.c_str());
123
124
2/2
✓ Branch 0 taken 1391029 times.
✓ Branch 1 taken 757187 times.
2148216 if (context.size())
125
3/6
✓ Branch 0 taken 1391029 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1391029 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1391029 times.
✗ Branch 5 not taken.
1391029 current_zasm_context = fmt::format("{}", fmt::join(context, ", "));
126 else
127 {
128
1/2
✓ Branch 0 taken 757187 times.
✗ Branch 1 not taken.
757187 Z_scripterrlog("%s\n", text.c_str());
129 757187 return;
130 }
131
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 757187 times.
✓ Branch 2 taken 1391029 times.
2148216 }
132
133 1391029 Z_scripterrlog("%s | %s\n", current_zasm_context.c_str(), text.c_str());
134 1391029 current_zasm_context = "";
135 1391029 current_zasm_extra_context = "";
136 2148216 }
137
138 // (type, index) => ScriptEngineData
139 427 std::map<std::pair<ScriptType, int>, ScriptEngineData> scriptEngineDatas;
140
141 extern byte use_dwm_flush;
142 uint8_t using_SRAM = 0;
143
144 int32_t hangcount = 0;
145 bool can_neg_array = true;
146
147 extern byte monochrome_console;
148
149 427 static std::map<script_id, ScriptDebugHandle> script_debug_handles;
150 ScriptDebugHandle* runtime_script_debug_handle;
151
152 427 CScriptDrawingCommands scriptdraws;
153 427 FFScript FFCore;
154
155 static UserDataContainer<script_array, 1000000> script_arrays = {script_object_type::array, "array"};
156 static UserDataContainer<user_paldata, MAX_USER_PALDATAS> user_paldatas = {script_object_type::paldata, "paldata"};
157 static UserDataContainer<user_rng, MAX_USER_RNGS> user_rngs = {script_object_type::rng, "rng"};
158 static UserDataContainer<user_stack, MAX_USER_STACKS> user_stacks = {script_object_type::stack, "stack"};
159 static UserDataContainer<user_bitmap, MAX_USER_BITMAPS> user_bitmaps = {script_object_type::bitmap, "bitmap"};
160
161 8088 script_array* create_script_array()
162 {
163 8088 return script_arrays.create();
164 }
165
166 398 void register_existing_script_array(script_array* array)
167 {
168 398 script_arrays.register_existing(array);
169 398 }
170
171 68 std::vector<script_array*> get_script_arrays()
172 {
173 68 std::vector<script_array*> result;
174
3/4
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 68 times.
✓ Branch 3 taken 552 times.
620 for (auto id : script_object_ids_by_type[script_arrays.type])
175 {
176
2/4
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 552 times.
✗ Branch 3 not taken.
552 result.push_back(&script_arrays[id]);
177 }
178 68 return result;
179
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 }
180
181 26 static script_array* find_or_create_internal_script_array(script_array::internal_array_id internal_id)
182 {
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (!zasm_array_supports(internal_id.zasm_var))
184 {
185 scripting_log_error_with_context("Invalid internal array id: {}", internal_id.zasm_var);
186 return nullptr;
187 }
188
189
2/2
✓ Branch 0 taken 1012 times.
✓ Branch 1 taken 10 times.
1022 for (auto id : script_object_ids_by_type[script_arrays.type])
190 {
191 1012 auto object = static_cast<script_array*>(get_script_object_checked(id));
192
5/6
✓ Branch 0 taken 1012 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 978 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 16 times.
1012 if (!object->internal_expired && object->internal_id.has_value() && object->internal_id.value() == internal_id)
193 16 return object;
194 }
195
196 10 auto array = script_arrays.create();
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (array)
198 {
199 10 array->arr.setValid(true);
200 10 array->internal_id = internal_id;
201 10 }
202 10 return array;
203 26 }
204
205 2533068 static void expire_internal_script_arrays(ScriptType scriptType, int ref)
206 {
207
2/2
✓ Branch 0 taken 1176374 times.
✓ Branch 1 taken 1356694 times.
2533068 if (!ZScriptVersion::gc_arrays())
208 1356694 return;
209
210 // Expire internal arrays referring to this script object.
211
2/2
✓ Branch 0 taken 1176374 times.
✓ Branch 1 taken 20411646 times.
21588020 for (auto& script_object : script_objects | std::views::values)
212 {
213
2/2
✓ Branch 0 taken 8808754 times.
✓ Branch 1 taken 11602892 times.
20411646 if (script_object->type != script_object_type::array)
214 8808754 continue;
215
216 11602892 auto array = static_cast<script_array*>(script_object.get());
217
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 11602884 times.
11602892 if (!array->internal_id.has_value())
218 11602884 continue;
219
220
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 if (array->internal_id->matches(scriptType, ref))
221 2 array->internal_expired = true;
222 }
223 2533068 }
224
225 37530 static void expire_internal_script_arrays(ScriptType scriptType)
226 {
227
2/2
✓ Branch 0 taken 19128 times.
✓ Branch 1 taken 18402 times.
37530 if (!ZScriptVersion::gc_arrays())
228 18402 return;
229
230 // Expire internal arrays referring to this script object.
231
2/2
✓ Branch 0 taken 19128 times.
✓ Branch 1 taken 109071 times.
128199 for (auto& script_object : script_objects | std::views::values)
232 {
233
2/2
✓ Branch 0 taken 10213 times.
✓ Branch 1 taken 98858 times.
109071 if (script_object->type != script_object_type::array)
234 10213 continue;
235
236 98858 auto array = static_cast<script_array*>(script_object.get());
237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98858 times.
98858 if (!array->internal_id.has_value())
238 98858 continue;
239
240 if (array->internal_id->matches(scriptType))
241 array->internal_expired = true;
242 }
243 37530 }
244
245 153275782 script_array* checkArray(uint32_t id, bool skipError)
246 {
247 153275782 return script_arrays.check(id, skipError);
248 }
249
250 16869237 void script_bitmaps::update()
251 {
252 16869237 auto ids = script_object_ids_by_type[user_bitmaps.type];
253
2/2
✓ Branch 0 taken 41321692 times.
✓ Branch 1 taken 16869237 times.
58190929 for (auto id : ids)
254 {
255
1/2
✓ Branch 0 taken 41321692 times.
✗ Branch 1 not taken.
41321692 auto& bitmap = user_bitmaps[id];
256
3/4
✓ Branch 0 taken 41321692 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1509228 times.
✓ Branch 3 taken 39812464 times.
41321692 if (bitmap.is_freeing())
257 {
258
1/2
✓ Branch 0 taken 1509228 times.
✗ Branch 1 not taken.
1509228 bitmap.mark_can_del();
259
1/2
✓ Branch 0 taken 1509228 times.
✗ Branch 1 not taken.
1509228 delete_script_object(id);
260 1509228 }
261 }
262 16869237 }
263
264 380411 user_bitmap& script_bitmaps::get(int32_t id)
265 {
266
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 380403 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
380411 static user_bitmap fake;
267
268 380411 current_zasm_context = "script drawing";
269
1/2
✓ Branch 0 taken 380411 times.
✗ Branch 1 not taken.
380411 if (auto bitmap = user_bitmaps.check(id))
270 {
271 380411 current_zasm_context = "";
272 380411 return *bitmap;
273 }
274
275 return fake;
276 380411 }
277
278 script_bitmaps scb;
279 427 user_rng nulrng;
280 427 zc_randgen script_rnggens[MAX_USER_RNGS];
281
282 FONT *get_zc_font(int index);
283
284 int32_t combopos_modified = -1;
285 static std::vector<word> combo_id_cache;
286
287 int32_t CScriptDrawingCommands::GetCount()
288 {
289 al_trace("current number of draws is: %d\n", count);
290 return count;
291 }
292
293 // Decodes a `mapdataref` (reference number) for a temporary screen.
294 //
295 // A mapdataref can refer to:
296 //
297 // - the canonical mapscr data, loaded via `Game->LoadMapData(int map, int screen)`
298 // - a temporary mapscr, loaded via `Game->LoadTempScreen(int layer, int? screen)`
299 // - a temporary mapscr, loaded via `Game->LoadScrollingScreen(int layer, int? screen)`
300 //
301 // The canonical maprefs are >=0, and temporary ones are all negative.
302 //
303 // If temporary, and loaded without specifiying a screen index, we allow combo array variables (like
304 // `ComboX[pos]`) to address any rpos in the region. Otherwise, only positions in the exact screen
305 // referenced by `mapdataref` can be used (0-175). See ResolveMapdataPos.
306 132609693 mapdata decode_mapdata_ref(int ref)
307 {
308
2/2
✓ Branch 0 taken 37064919 times.
✓ Branch 1 taken 95544774 times.
132609693 if (ref >= 0)
309 {
310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37064919 times.
37064919 if (ref >= TheMaps.size())
311 return mapdata{};
312
313 37064919 int screen = ref % MAPSCRS;
314 37064919 return mapdata{mapdata_type::CanonicalScreen, &TheMaps[ref], screen, 0};
315 }
316
317 // Negative values are for temporary screens.
318
319 95544774 ref = -(ref + 1);
320 95544774 bool is_scrolling = ref & 1;
321 95544774 bool is_region = ref & 2;
322 95544774 int screen = (ref & 0x0000FF00) >> 8;
323 95544774 int layer = (ref & 0x00FF0000) >> 16;
324
325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95544774 times.
95544774 if (is_region)
326 {
327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95544774 times.
95544774 if (is_scrolling)
328 screen = scrolling_region.origin_screen;
329 else
330 95544774 screen = cur_screen;
331 95544774 }
332
333 95544774 mapscr* scr = nullptr;
334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95544774 times.
95544774 if (is_scrolling)
335 {
336 int index = screen * 7 + layer;
337 if (index >= 0 && index < FFCore.ScrollingScreensAll.size())
338 scr = FFCore.ScrollingScreensAll[index];
339 }
340 else
341 {
342
3/6
✓ Branch 0 taken 95544774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 95544774 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 95544774 times.
95544774 if (layer >= 0 && layer <= 6 && is_in_current_region(screen))
343 95544774 scr = get_scr_layer(screen, layer);
344 }
345
346
1/2
✓ Branch 0 taken 95544774 times.
✗ Branch 1 not taken.
95544774 if (!scr)
347 return mapdata{};
348
349 95544774 auto type = mapdata_type::None;
350
2/4
✓ Branch 0 taken 95544774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 95544774 times.
✗ Branch 3 not taken.
95544774 if (is_region && is_scrolling)
351 type = mapdata_type::TemporaryScrollingRegion;
352
2/4
✓ Branch 0 taken 95544774 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 95544774 times.
95544774 else if (is_region && !is_scrolling)
353 95544774 type = mapdata_type::TemporaryCurrentRegion;
354 else if (!is_region && is_scrolling)
355 type = mapdata_type::TemporaryScrollingScreen;
356 else if (!is_region && !is_scrolling)
357 type = mapdata_type::TemporaryCurrentScreen;
358
359 95544774 return mapdata{type, scr, screen, layer};
360 132609693 }
361
362 3767772 static int create_mapdata_temp_ref(mapdata_type type, int screen, int layer)
363 {
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3767772 times.
3767772 bool is_scrolling = type == mapdata_type::TemporaryScrollingScreen || type == mapdata_type::TemporaryScrollingRegion;
365
2/2
✓ Branch 0 taken 182518 times.
✓ Branch 1 taken 3585254 times.
3767772 bool is_region = type == mapdata_type::TemporaryScrollingRegion || type == mapdata_type::TemporaryCurrentRegion;
366
367 3767772 int ref = 0;
368 3767772 ref |= is_scrolling ? 1 : 0;
369 3767772 ref |= is_region ? 2 : 0;
370
1/2
✓ Branch 0 taken 3767772 times.
✗ Branch 1 not taken.
3767772 if (!is_region)
371 ref |= ((screen & 0xFF) << 8);
372 3767772 ref |= ((layer & 0xFF) << 16);
373 3767772 return -ref-1;
374 }
375
376 mapscr* GetScrollingMapscr(int layer, int x, int y)
377 {
378 if (!screenscrolling)
379 return nullptr;
380
381 int screen = scrolling_region.origin_screen + map_scr_xy_to_index(x / 256, y / 176);
382 mapscr* m = FFCore.ScrollingScreensAll[screen * 7 + layer];
383 if (!m || !m->is_valid())
384 return nullptr;
385
386 return m;
387 }
388
389 151527 int32_t getMap(int32_t ref)
390 {
391
1/15
✗ Branch 0 not taken.
✓ Branch 1 taken 151527 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
151527 switch(ref)
392 {
393 case MAPSCR_TEMP0:
394 return cur_map+1;
395 case MAPSCR_TEMP1:
396 return origin_scr->layermap[0];
397 case MAPSCR_TEMP2:
398 return origin_scr->layermap[1];
399 case MAPSCR_TEMP3:
400 return origin_scr->layermap[2];
401 case MAPSCR_TEMP4:
402 return origin_scr->layermap[3];
403 case MAPSCR_TEMP5:
404 return origin_scr->layermap[4];
405 case MAPSCR_TEMP6:
406 return origin_scr->layermap[5];
407 case MAPSCR_SCROLL0:
408 return scrolling_map+1;
409 case MAPSCR_SCROLL1:
410 return special_warp_return_scr->layermap[0];
411 case MAPSCR_SCROLL2:
412 return special_warp_return_scr->layermap[1];
413 case MAPSCR_SCROLL3:
414 return special_warp_return_scr->layermap[2];
415 case MAPSCR_SCROLL4:
416 return special_warp_return_scr->layermap[3];
417 case MAPSCR_SCROLL5:
418 return special_warp_return_scr->layermap[4];
419 case MAPSCR_SCROLL6:
420 return special_warp_return_scr->layermap[5];
421 default:
422 151527 return (ref / MAPSCRS + 1);
423 }
424 151527 }
425 314379 int32_t getScreen(int32_t ref)
426 {
427
1/15
✗ Branch 0 not taken.
✓ Branch 1 taken 314379 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
314379 switch(ref)
428 {
429 case MAPSCR_TEMP0:
430 return cur_screen;
431 case MAPSCR_TEMP1:
432 return origin_scr->layerscreen[0];
433 case MAPSCR_TEMP2:
434 return origin_scr->layerscreen[1];
435 case MAPSCR_TEMP3:
436 return origin_scr->layerscreen[2];
437 case MAPSCR_TEMP4:
438 return origin_scr->layerscreen[3];
439 case MAPSCR_TEMP5:
440 return origin_scr->layerscreen[4];
441 case MAPSCR_TEMP6:
442 return origin_scr->layerscreen[5];
443 case MAPSCR_SCROLL0:
444 return scrolling_hero_screen;
445 case MAPSCR_SCROLL1:
446 return special_warp_return_scr->layerscreen[0];
447 case MAPSCR_SCROLL2:
448 return special_warp_return_scr->layerscreen[1];
449 case MAPSCR_SCROLL3:
450 return special_warp_return_scr->layerscreen[2];
451 case MAPSCR_SCROLL4:
452 return special_warp_return_scr->layerscreen[3];
453 case MAPSCR_SCROLL5:
454 return special_warp_return_scr->layerscreen[4];
455 case MAPSCR_SCROLL6:
456 return special_warp_return_scr->layerscreen[5];
457 default:
458 314379 return (ref % MAPSCRS);
459 }
460 314379 }
461
462 655056392 static ffcdata* get_ffc(ffc_id_t ffc_id)
463 {
464 655056392 return &get_scr_for_region_index_offset(ffc_id / MAXFFCS)->getFFC(ffc_id % MAXFFCS);
465 }
466
467 105844 dword get_subref(int sub, byte ty, byte pg, word ind)
468 {
469 byte s;
470
2/2
✓ Branch 0 taken 79480 times.
✓ Branch 1 taken 26364 times.
105844 if(sub == -1) //special; load current
471 {
472
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26364 times.
26364 if (new_sub_indexes[ty] < 0) return 0;
473 26364 s = new_sub_indexes[ty];
474 26364 }
475
1/2
✓ Branch 0 taken 79480 times.
✗ Branch 1 not taken.
79480 else if(unsigned(sub) < 256)
476 79480 s = sub;
477 else return 0;
478 105844 ++ty; //type is offset by 1
479 105844 return (s<<24)|(pg<<16)|((ty&0x7)<<13)|(ind&0x1FFF);
480 105844 }
481 425312 std::tuple<byte,int8_t,byte,word> from_subref(dword ref)
482 {
483 425312 byte type = (ref>>13)&0x07;
484
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 425312 times.
425312 if(!type)
485 return { 0, -1, 0, 0 };
486
487 425312 byte sub = (ref>>24)&0xFF;
488 425312 byte pg = (ref>>16)&0xFF;
489 425312 word ind = (ref)&0x1FFF;
490 425312 return { sub, type-1, pg, ind };
491 425312 }
492
493 345835 std::tuple<ZCSubscreen*,SubscrPage*,SubscrWidget*,byte> load_subscreen_ref(dword ref)
494 {
495 1729175 auto [sub,ty,pg,ind] = from_subref(ref);
496 345835 ZCSubscreen* sbscr = nullptr;
497 345835 SubscrPage* sbpg = nullptr;
498 345835 SubscrWidget* sbwidg = nullptr;
499
1/5
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
345835 switch(ty)
500 {
501 case sstACTIVE:
502
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
345835 if(sub < subscreens_active.size())
503 345835 sbscr = &subscreens_active[sub];
504 345835 break;
505 case sstPASSIVE:
506 if(sub < subscreens_passive.size())
507 sbscr = &subscreens_passive[sub];
508 break;
509 case sstOVERLAY:
510 if(sub < subscreens_overlay.size())
511 sbscr = &subscreens_overlay[sub];
512 break;
513 case sstMAP:
514 if(sub < subscreens_map.size())
515 sbscr = &subscreens_map[sub];
516 break;
517 }
518
1/2
✓ Branch 0 taken 345835 times.
✗ Branch 1 not taken.
345835 if(sbscr)
519 {
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
345835 if(pg < sbscr->pages.size())
521 691670 sbpg = &sbscr->pages[pg];
522 345835 }
523 else return { nullptr, nullptr, nullptr, -1 }; //no subscreen
524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
345835 if(sbpg)
525 {
526
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 345835 times.
345835 if(ind < sbpg->size())
527 691670 sbwidg = sbpg->at(ind);
528 345835 }
529 345835 return { sbscr, sbpg, sbwidg, ty };
530 345835 }
531 186065 std::pair<ZCSubscreen*,byte> load_subdata(dword ref)
532 {
533 186065 auto [sub,_pg,_widg,ty] = load_subscreen_ref(ref);
534 186065 return { sub, ty };
535 }
536 56028 std::pair<SubscrPage*,byte> load_subpage(dword ref)
537 {
538 56028 auto [_sub,pg,_widg,ty] = load_subscreen_ref(ref);
539 56028 return { pg, ty };
540 }
541 103742 std::pair<SubscrWidget*,byte> load_subwidg(dword ref)
542 {
543 103742 auto [_sub,_pg,widg,ty] = load_subscreen_ref(ref);
544 103742 return { widg, ty };
545 }
546
547 #include "zconsole/ConsoleLogger.h"
548
549 //no ifdef here
550 extern CConsoleLoggerEx zscript_coloured_console;
551
552 bool FFScript::isNumber(char chr)
553 {
554 if ( chr >= '0' )
555 {
556 if ( chr <= '9' ) return true;
557 }
558 return false;
559 }
560
561 int32_t FFScript::ilen(char *p)
562 {
563 int32_t ret = 0; int32_t pos = 0;
564 if(p[pos] == '-')
565 ret++;
566 for(; FFCore.isNumber(p[pos + ret]); ++ret);
567 return ret;
568 }
569
570 int32_t FFScript::atox(char *ip_str)
571 {
572 char tmp[2]={'2','\0'};
573 int32_t op_val=0, i=0, ip_len = strlen(ip_str);
574
575 if(strncmp(ip_str, "0x", 2) == 0)
576 {
577 ip_str +=2;
578 ip_len -=2;
579 }
580
581 for(i=0;i<ip_len;i++)
582 {
583 op_val *= 0x10;
584 switch(ip_str[i])
585 {
586 case 'a':
587 op_val += 0xa;
588 break;
589 case 'b':
590 op_val += 0xb;
591 break;
592 case 'c':
593 op_val += 0xc;
594 break;
595 case 'd':
596 op_val += 0xd;
597 break;
598 case 'e':
599 op_val += 0xe;
600 break;
601 case 'f':
602 op_val += 0xf;
603 break;
604 case '0':
605 case '1':
606 case '2':
607 case '3':
608 case '4':
609 case '5':
610 case '6':
611 case '7':
612 case '8':
613 case '9':
614 tmp[0] = ip_str[i];
615 op_val += atoi(tmp);
616 break;
617 default :
618 op_val += 0x0;
619 break;
620 }
621 }
622 return op_val;
623 }
624
625 char runningItemScripts[256] = {0};
626
627 extern int32_t directItemA;
628 extern int32_t directItemB;
629 extern int32_t directItemX;
630 extern int32_t directItemY;
631
632
633 #ifdef _MSC_VER
634 #pragma warning ( disable : 4800 ) //int32_t to bool town. population: lots.
635 #endif
636
637 //! New datatype vars for 2.54:
638
639 //spritedata sp->member
640
641
642 using std::string;
643
644 extern char *guy_string[];
645 extern int32_t skipcont;
646
647 PALETTE tempgreypal; //Palettes go here. This is used for Greyscale() / Monochrome()
648 PALETTE userPALETTE[256]; //Palettes go here. This is used for Greyscale() / Monochrome()
649 PALETTE tempblackpal; //Used for storing the palette while fading to black
650
651 byte FF_hero_action; //This way, we can make safe replicas of internal Hero actions to be set by script.
652
653 int32_t FF_screenbounds[4]; //edges of the screen, left, right, top, bottom used for where to scroll.
654 int32_t FF_screen_dimensions[4]; //height, width, displaywidth, displayheight
655 int32_t FF_subscreen_dimensions[4];
656 int32_t FF_eweapon_removal_bounds[4]; //left, right, top, bottom coordinates for automatic eweapon removal.
657 int32_t FF_lweapon_removal_bounds[4]; //left, right, top, bottom coordinates for automatic lweapon removal.
658 int32_t FF_clocks[FFSCRIPTCLASS_CLOCKS]; //Will be used for Heroaction, anims, and so forth
659 byte ScriptDrawingRules[SCRIPT_DRAWING_RULES];
660 int32_t FF_UserMidis[NUM_USER_MIDI_OVERRIDES]; //MIDIs to use for Game Over, and similar to override system defaults.
661
662 //We gain some speed by not passing as arguments
663 int32_t sarg1;
664 int32_t sarg2;
665 int32_t sarg3;
666 vector<int32_t> *sargvec;
667 string *sargstr;
668 refInfo *ri;
669 script_data *curscript;
670 int32_t(*stack)[MAX_STACK_SIZE];
671 int32_t(*ret_stack)[MAX_CALL_FRAMES];
672 vector<int32_t> zs_vargs;
673 ScriptType curScriptType;
674 word curScriptNum;
675 int32_t curScriptIndex;
676 bool script_funcrun;
677 string* destructstr;
678 size_t gen_frozen_index;
679
680 static vector<ScriptType> curScriptType_cache;
681 static vector<int32_t> curScriptNum_cache;
682 static vector<int32_t> curScriptIndex_cache;
683 static vector<int32_t> sarg1cache;
684 static vector<int32_t> sarg2cache;
685 static vector<int32_t> sarg3cache;
686 static vector<vector<int32_t>*> sargvec_cache;
687 static vector<string*> sargstr_cache;
688 static vector<refInfo*> ricache;
689 static vector<script_data*> sdcache;
690 static vector<int32_t(*)[MAX_STACK_SIZE]> stackcache;
691 static vector<int32_t(*)[MAX_CALL_FRAMES]> ret_stack_cache;
692 231205 void push_ri()
693 {
694 231205 sarg1cache.push_back(sarg1);
695 231205 sarg2cache.push_back(sarg2);
696 231205 sarg3cache.push_back(sarg3);
697 231205 curScriptType_cache.push_back(curScriptType);
698 231205 curScriptNum_cache.push_back(curScriptNum);
699 231205 curScriptIndex_cache.push_back(curScriptIndex);
700 231205 sargvec_cache.push_back(sargvec);
701 231205 sargstr_cache.push_back(sargstr);
702 231205 ricache.push_back(ri);
703 231205 sdcache.push_back(curscript);
704 231205 stackcache.push_back(stack);
705 231205 ret_stack_cache.push_back(ret_stack);
706 231205 }
707 231205 void pop_ri()
708 {
709 231205 sarg1 = sarg1cache.back(); sarg1cache.pop_back();
710 231205 sarg2 = sarg2cache.back(); sarg2cache.pop_back();
711 231205 sarg3 = sarg3cache.back(); sarg3cache.pop_back();
712 231205 curScriptType = curScriptType_cache.back(); curScriptType_cache.pop_back();
713 231205 curScriptNum = curScriptNum_cache.back(); curScriptNum_cache.pop_back();
714 231205 curScriptIndex = curScriptIndex_cache.back(); curScriptIndex_cache.pop_back();
715 231205 sargvec = sargvec_cache.back(); sargvec_cache.pop_back();
716 231205 sargstr = sargstr_cache.back(); sargstr_cache.pop_back();
717 231205 ri = ricache.back(); ricache.pop_back();
718 231205 curscript = sdcache.back(); sdcache.pop_back();
719 231205 stack = stackcache.back(); stackcache.pop_back();
720 231205 ret_stack = ret_stack_cache.back(); ret_stack_cache.pop_back();
721 231205 }
722
723 //START HELPER FUNCTIONS
724 ///-------------------------------------//
725 // Helper Functions //
726 ///-------------------------------------//
727
728 2 static void log_stack_overflow_error()
729 {
730
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 scripting_log_error_with_context("Stack overflow!");
731 2 }
732
733 2 static void log_call_limit_error()
734 {
735 2 scripting_log_error_with_context("Function call limit reached! Too much recursion. Max nested function calls is {}", MAX_CALL_FRAMES);
736 2 }
737
738 41593604 void SH::write_stack(const uint32_t sp, const int32_t value)
739 {
740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41593604 times.
41593604 if (sp >= MAX_STACK_SIZE)
741 {
742 log_stack_overflow_error();
743 ri->overflow = true;
744 return;
745 }
746
747 41593604 (*stack)[sp] = value;
748 41593604 }
749
750 984586484 int32_t SH::read_stack(const uint32_t sp)
751 {
752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 984586484 times.
984586484 if (sp >= MAX_STACK_SIZE)
753 {
754 log_stack_overflow_error();
755 ri->overflow = true;
756 return -10000;
757 }
758
759 984586484 return (*stack)[sp];
760 984586484 }
761
762 ///----------------------------//
763 // Misc. //
764 ///----------------------------//
765
766 byte flagpos;
767 int32_t flagval;
768 21612004 void clear_ornextflag()
769 {
770 21612004 flagpos = 0;
771 21612004 flagval = 0;
772 21612004 }
773 147024201 void ornextflag(bool flag)
774 {
775
2/2
✓ Branch 0 taken 144842444 times.
✓ Branch 1 taken 2181757 times.
147024201 if(flag) flagval |= 1<<flagpos;
776 147024201 ++flagpos;
777 147024201 }
778
779 11180909 int32_t get_screenflags(mapscr *m, int32_t flagset)
780 {
781 11180909 clear_ornextflag();
782
783
5/11
✓ Branch 0 taken 4822494 times.
✓ Branch 1 taken 6266256 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 52 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 92096 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
11180909 switch(flagset)
784 {
785 case 0: // Room Type
786 4822494 ornextflag(m->flags6&1);
787 4822494 ornextflag(m->flags6&2);
788 4822494 ornextflag(m->flags7&8);
789 4822494 break;
790
791 case 1: // View
792 6266256 ornextflag(m->flags3&8);
793 6266256 ornextflag(m->flags7&16);
794 6266256 ornextflag(m->flags3&16);
795 6266256 ornextflag(m->flags3&64);
796 6266256 ornextflag(m->flags7&2);
797 6266256 ornextflag(m->flags7&1);
798 6266256 ornextflag(m->flags&fDARK);
799 6266256 ornextflag(m->flags9&fDARK_DITHER);
800 6266256 ornextflag(m->flags9&fDARK_TRANS);
801 6266256 break;
802
803 case 2: // Secrets
804 11 ornextflag(m->flags&1);
805 11 ornextflag(m->flags5&16);
806 11 ornextflag(m->flags6&4);
807 11 ornextflag(m->flags6&32);
808 11 break;
809
810 case 3: // Warp
811 ornextflag(m->flags5&4);
812 ornextflag(m->flags5&8);
813 ornextflag(m->flags&64);
814 ornextflag(m->flags8&64);
815 ornextflag(m->flags3&32);
816 ornextflag(m->flags9&fDISABLE_MIRROR);
817 ornextflag(m->flags10&fMAZE_CAN_GET_LOST);
818 ornextflag(m->flags10&fMAZE_LOOPY);
819 break;
820
821 case 4: // Item
822 52 ornextflag(m->flags3&1);
823 52 ornextflag(m->flags7&4);
824 52 ornextflag(m->flags8&0x40);
825 52 ornextflag(m->flags8&0x80);
826 52 ornextflag(m->flags9&0x01);
827 52 ornextflag(m->flags9&0x02);
828 52 ornextflag(m->flags9&fBELOWRETURN);
829 52 break;
830
831 case 5: // Combo
832 ornextflag((m->flags2>>4)&2);
833 ornextflag(m->flags3&2);
834 ornextflag(m->flags5&2);
835 ornextflag(m->flags6&64);
836 break;
837
838 case 6: // Save
839 ornextflag(m->flags4&64);
840 ornextflag(m->flags4&128);
841 ornextflag(m->flags6&8);
842 ornextflag(m->flags6&16);
843 break;
844
845 case 7: // FFC
846 ornextflag(m->flags6&128);
847 ornextflag(m->flags5&128);
848 break;
849
850 case 8: // Whistle
851 ornextflag(m->flags&16);
852 ornextflag(m->flags7&64);
853 ornextflag(m->flags7&128);
854 break;
855
856 case 9: // Misc
857 92096 ornextflag(m->flags&32);
858 92096 ornextflag(m->flags5&64);
859 92096 flagval |= m->flags8<<2;
860 92096 break;
861 }
862
863 11180909 return flagval;
864 }
865
866 4476010 int32_t get_screeneflags(mapscr *m, int32_t flagset)
867 {
868 4476010 clear_ornextflag();
869
870
2/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 4475708 times.
✓ Branch 3 taken 302 times.
4476010 switch(flagset)
871 {
872 case 0:
873 flagval |= m->flags11&0x1F;
874 break;
875
876 case 1:
877 4475708 ornextflag(m->flags11&32);
878 4475708 ornextflag(m->flags11&64);
879 4475708 ornextflag(m->flags3&4);
880 4475708 ornextflag(m->flags11&128);
881 4475708 ornextflag((m->flags2>>4)&4);
882 4475708 break;
883
884 case 2:
885 302 ornextflag(m->flags3&128);
886 302 ornextflag(m->flags&2);
887 302 ornextflag((m->flags2>>4)&8);
888 302 ornextflag(m->flags4&16);
889 302 ornextflag(m->flags9&fENEMY_WAVES);
890 302 break;
891 }
892
893 4476010 return flagval;
894 }
895
896 551246 int32_t get_mi(mapdata const& ref)
897 {
898
1/2
✓ Branch 0 taken 551246 times.
✗ Branch 1 not taken.
551246 if (ref.canonical())
899 {
900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 551246 times.
551246 if (ref.screen >= MAPSCRSNORMAL) return -1;
901 551246 return mapind(ref.scr->map, ref.screen);
902 }
903 else if (ref.current())
904 {
905 if (ref.screen >= MAPSCRSNORMAL) return -1;
906 return mapind(cur_map, ref.screen);
907 }
908 else if (ref.scrolling())
909 {
910 if (ref.screen >= MAPSCRSNORMAL) return -1;
911 return mapind(scrolling_map, ref.screen);
912 }
913
914 return -1;
915 551246 }
916 int32_t get_mi(int32_t ref)
917 {
918 return get_mi(decode_mapdata_ref(ref));
919 }
920
921 int32_t get_ref_map_index(int32_t ref)
922 {
923 if (ref >= 0)
924 return ref;
925
926 auto result = decode_mapdata_ref(ref);
927 if (result.current())
928 {
929 return map_screen_index(cur_map, result.screen);
930 }
931 else if (result.scrolling())
932 {
933 return map_screen_index(scrolling_map, result.screen);
934 }
935
936 return -1;
937 }
938
939 template <typename T>
940 348967704 static T* ResolveSprite(int32_t uid, const char* name)
941 {
942
8/10
✓ Branch 0 taken 109873576 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1642483 times.
✓ Branch 3 taken 597888 times.
✓ Branch 4 taken 169197370 times.
✓ Branch 5 taken 2612 times.
✓ Branch 6 taken 61041696 times.
✓ Branch 7 taken 183114 times.
✓ Branch 8 taken 6428965 times.
✗ Branch 9 not taken.
348967704 if (!uid)
943 {
944
6/20
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 597888 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 597888 times.
✓ Branch 8 taken 2612 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2612 times.
✓ Branch 12 taken 183114 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 183114 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
783614 scripting_log_error_with_context("Invalid sprite: null pointer");
945 783614 return nullptr;
946 }
947
948
8/10
✗ Branch 0 not taken.
✓ Branch 1 taken 109873576 times.
✓ Branch 2 taken 180 times.
✓ Branch 3 taken 1642303 times.
✓ Branch 4 taken 7108 times.
✓ Branch 5 taken 169190262 times.
✓ Branch 6 taken 20166 times.
✓ Branch 7 taken 61021530 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6428965 times.
348184090 if (auto s = sprite::getByUID(uid))
949 {
950
9/18
✗ Branch 0 not taken.
✓ Branch 1 taken 109873576 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1642303 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1642303 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 169190262 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 169190262 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 61021530 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 61021530 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 6428965 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 6428965 times.
348156636 if (auto s2 = dynamic_cast<T*>(s))
951 348156636 return s2;
952
953 scripting_log_error_with_context("Invalid sprite using UID = {} - but that sprite is not a {}", uid, name);
954 return nullptr;
955 }
956
957 27454 scripting_log_error_with_context("Invalid sprite using UID = {} - but that sprite does not exist", uid);
958 27454 return nullptr;
959 348967704 }
960
961 109873576 sprite* ResolveBaseSprite(int32_t uid)
962 {
963 109873576 return ResolveSprite<sprite>(uid, "sprite");
964 }
965
966 2240371 item* ResolveItemSprite(int32_t uid)
967 {
968 2240371 return ResolveSprite<item>(uid, "item");
969 }
970
971 169199970 enemy* ResolveNpc(int32_t uid)
972 {
973 169199970 return ResolveSprite<enemy>(uid, "npc");
974 }
975
976 static weapon* ResolveEWeapon_checkSpriteList(int32_t uid)
977 {
978 // Check here first (for the error logging.)
979 const char* name = "eweapon";
980 auto spr = ResolveSprite<weapon>(uid, name);
981
982 // Double check this is from the right sprite list.
983 if (spr && !Ewpns.getByUID(uid))
984 {
985 scripting_log_error_with_context("Invalid sprite using UID = {} - but that sprite is not a {}", uid, name);
986 return nullptr;
987 }
988
989 return spr;
990 }
991
992 598 static weapon* ResolveLWeapon_checkSpriteList(int32_t uid)
993 {
994 // Check here first (for the error logging.)
995 598 const char* name = "lweapon";
996 598 auto spr = ResolveSprite<weapon>(uid, name);
997
998 // Double check this is from the right sprite list.
999
2/4
✓ Branch 0 taken 598 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 598 times.
598 if (spr && !Lwpns.getByUID(uid))
1000 {
1001 scripting_log_error_with_context("Invalid sprite using UID = {} - but that sprite is not a {}", uid, name);
1002 return nullptr;
1003 }
1004
1005 598 return spr;
1006 598 }
1007
1008 // For compat, get the first `combo_trigger` of the current `ri->combodataref`
1009 3224 combo_trigger* get_first_combo_trigger()
1010 {
1011 3224 int ref = GET_REF(combodataref);
1012
2/4
✓ Branch 0 taken 3224 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3224 times.
3224 if(ref < 0 || ref > (MAXCOMBOS-1) )
1013 return nullptr;
1014
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 3085 times.
3224 if(combobuf[ref].triggers.empty())
1015 139 return &(combobuf[ref].triggers.emplace_back());
1016 3085 return &(combobuf[ref].triggers[0]);
1017 3224 }
1018 // Get the combo trigger pointed to by `ref` (usually ri->combotriggerref)
1019 combo_trigger* get_combo_trigger(dword ref)
1020 {
1021 byte idx = (ref >> 24) & 0xFF;
1022 dword cid = ref & 0x00FFFFFF;
1023 if(cid >= MAXCOMBOS)
1024 {
1025 scripting_log_error_with_context("Invalid combotrigger ID: {}-{}", idx, cid);
1026 return nullptr;
1027 }
1028 newcombo& cmb = combobuf[cid];
1029 if(idx >= cmb.triggers.size())
1030 {
1031 scripting_log_error_with_context("Invalid combotrigger ID: {}-{}", idx, cid);
1032 return nullptr;
1033 }
1034 return &(cmb.triggers[idx]);
1035 }
1036 // Get the combo ID of the trigger pointed to by `ref` (usually ri->combotriggerref)
1037 dword get_combo_from_trigger_ref(dword ref)
1038 {
1039 dword cid = ref & 0x00FFFFFF;
1040 DCHECK(cid < MAXCOMBOS);
1041 return cid;
1042 }
1043
1044 ///------------------------------------------------//
1045 // Pointer Handling Functions //
1046 ///------------------------------------------------//
1047
1048 //LWeapon Helper
1049 class LwpnH : public SH
1050 {
1051
1052 public:
1053
1054
1055 static defWpnSprite getDefWeaponSprite(weapon *wp)
1056 {
1057 switch(wp->id)
1058 {
1059 case wNone: return ws_0;
1060 case wSword: return ws_0;
1061 case wBeam: return wsBeam;
1062 case wBrang : return wsBrang;
1063 case wBomb: return wsBomb;
1064 case wSBomb: return wsSBomb;
1065 case wLitBomb: return wsBombblast;
1066 case wLitSBomb: return wsBombblast;
1067 case wArrow: return wsArrow;
1068 case wRefArrow: return wsArrow;
1069 case wFire: return wsFire;
1070 case wRefFire: return wsFire;
1071 case wRefFire2: return wsFire;
1072 case wWhistle: return wsUnused45;
1073 case wBait: return wsBait;
1074 case wWand: return wsWandHandle;
1075 case wMagic: return wsMagic;
1076 case wCatching: return wsUnused45;
1077 case wWind: return wsWind;
1078 case wRefMagic: return wsRefMagic;
1079 case wRefFireball: return wsRefFireball;
1080 case wRefRock: return wsRock;
1081 case wHammer: return wsHammer;
1082 case wHookshot: return wsHookshotHead;
1083 case wHSHandle: return wsHookshotHandle;
1084 case wHSChain: return wsHookshotChainH;
1085 case wSSparkle: return wsSilverSparkle;
1086 case wFSparkle: return wsGoldSparkle;
1087 case wSmack: return wsHammerSmack;
1088 case wPhantom: return wsUnused45;
1089 case wCByrna: return wsByrnaCane;
1090 case wRefBeam: return wsRefBeam;
1091 case wStomp: return wsUnused45;
1092 case lwMax: return wsUnused45;
1093 case wScript1:
1094 case wScript2:
1095 case wScript3:
1096 case wScript4:
1097 case wScript5:
1098 case wScript6:
1099 case wScript7:
1100 case wScript8:
1101 case wScript9:
1102 case wScript10: return ws_0;
1103 case wIce: return wsIce; //new
1104 case wFlame: return wsEFire2; //new
1105 //not implemented; t/b/a
1106 case wSound:
1107 case wThrown:
1108 case wPot:
1109 case wLit:
1110 case wBombos:
1111 case wEther:
1112 case wQuake:
1113 case wSword180:
1114 case wSwordLA: return wsUnused45;
1115
1116 case ewFireball: return wsFireball2;
1117 case ewArrow: return wsEArrow;
1118 case ewBrang: return wsBrang;
1119 case ewSword: return wsEBeam;
1120 case ewRock: return wsRock;
1121 case ewMagic: return wsEMagic;
1122 case ewBomb: return wsEBomb;
1123 case ewSBomb: return wsESbomb;
1124 case ewLitBomb: return wsEBombblast;
1125 case ewLitSBomb: return wsESbombblast;
1126 case ewFireTrail: return wsEFiretrail;
1127 case ewFlame: return wsEFire;
1128 case ewWind: return wsEWind;
1129 case ewFlame2: return wsEFire2;
1130 case ewFlame2Trail: return wsEFiretrail2;
1131 case ewIce: return wsIce;
1132 case ewFireball2: return wsFireball2;
1133 default: return wsUnused45;
1134 }
1135 };
1136
1137 20064 static int32_t loadWeapon(const int32_t uid)
1138 {
1139 20064 tempweapon = ResolveSprite<weapon>(uid, "lweapon");
1140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20064 times.
20064 if (!tempweapon)
1141 return _InvalidSpriteUID;
1142
1143 20064 return _NoError;
1144 20064 }
1145
1146 20064 static INLINE weapon *getWeapon()
1147 {
1148 20064 return tempweapon;
1149 }
1150
1151 37723 static INLINE void clearTemp()
1152 {
1153 37723 tempweapon = NULL;
1154 37723 }
1155
1156 private:
1157
1158 static weapon *tempweapon;
1159 };
1160
1161 weapon *LwpnH::tempweapon = NULL;
1162
1163 //EWeapon Helper
1164 class EwpnH : public SH
1165 {
1166
1167 public:
1168
1169 defWpnSprite getDefWeaponSprite(weapon *wp)
1170 {
1171 switch(wp->id)
1172 {
1173 case wNone: return ws_0;
1174 case wSword: return ws_0;
1175 case wBeam: return wsBeam;
1176 case wBrang : return wsBrang;
1177 case wBomb: return wsBomb;
1178 case wSBomb: return wsSBomb;
1179 case wLitBomb: return wsBombblast;
1180 case wLitSBomb: return wsBombblast;
1181 case wArrow: return wsArrow;
1182 case wRefArrow: return wsArrow;
1183 case wFire: return wsFire;
1184 case wRefFire: return wsFire;
1185 case wRefFire2: return wsFire;
1186 case wWhistle: return wsUnused45;
1187 case wBait: return wsBait;
1188 case wWand: return wsWandHandle;
1189 case wMagic: return wsMagic;
1190 case wCatching: return wsUnused45;
1191 case wWind: return wsWind;
1192 case wRefMagic: return wsRefMagic;
1193 case wRefFireball: return wsRefFireball;
1194 case wRefRock: return wsRock;
1195 case wHammer: return wsHammer;
1196 case wHookshot: return wsHookshotHead;
1197 case wHSHandle: return wsHookshotHandle;
1198 case wHSChain: return wsHookshotChainH;
1199 case wSSparkle: return wsSilverSparkle;
1200 case wFSparkle: return wsGoldSparkle;
1201 case wSmack: return wsHammerSmack;
1202 case wPhantom: return wsUnused45;
1203 case wCByrna: return wsByrnaCane;
1204 case wRefBeam: return wsRefBeam;
1205 case wStomp: return wsUnused45;
1206 case lwMax: return wsUnused45;
1207 case wScript1:
1208 case wScript2:
1209 case wScript3:
1210 case wScript4:
1211 case wScript5:
1212 case wScript6:
1213 case wScript7:
1214 case wScript8:
1215 case wScript9:
1216 case wScript10: return ws_0;
1217 case wIce: return wsIce; //new
1218 case wFlame: return wsEFire2; //new
1219 //not implemented; t/b/a
1220 case wSound:
1221 case wThrown:
1222 case wPot:
1223 case wLit:
1224 case wBombos:
1225 case wEther:
1226 case wQuake:
1227 case wSword180:
1228 case wSwordLA: return wsUnused45;
1229
1230 case ewFireball: return wsFireball2;
1231 case ewArrow: return wsEArrow;
1232 case ewBrang: return wsBrang;
1233 case ewSword: return wsEBeam;
1234 case ewRock: return wsRock;
1235 case ewMagic: return wsEMagic;
1236 case ewBomb: return wsEBomb;
1237 case ewSBomb: return wsESbomb;
1238 case ewLitBomb: return wsEBombblast;
1239 case ewLitSBomb: return wsESbombblast;
1240 case ewFireTrail: return wsEFiretrail;
1241 case ewFlame: return wsEFire;
1242 case ewWind: return wsEWind;
1243 case ewFlame2: return wsEFire2;
1244 case ewFlame2Trail: return wsEFiretrail2;
1245 case ewIce: return wsIce;
1246 case ewFireball2: return wsFireball2;
1247 default: return wsUnused45;
1248 }
1249 };
1250
1251 296065 static int32_t loadWeapon(const int32_t uid)
1252 {
1253 296065 tempweapon = ResolveSprite<weapon>(uid, "eweapon");
1254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 296065 times.
296065 if (!tempweapon)
1255 return _InvalidSpriteUID;
1256
1257 296065 return _NoError;
1258 296065 }
1259
1260 296065 static INLINE weapon *getWeapon()
1261 {
1262 296065 return tempweapon;
1263 }
1264
1265 37723 static INLINE void clearTemp()
1266 {
1267 37723 tempweapon = NULL;
1268 37723 }
1269
1270 private:
1271
1272 static weapon *tempweapon;
1273 };
1274
1275 weapon *EwpnH::tempweapon = NULL;
1276
1277 37723 void clearScriptHelperData()
1278 {
1279 37723 GuyH::clearTemp();
1280 37723 LwpnH::clearTemp();
1281 37723 EwpnH::clearTemp();
1282 37723 ItemH::clearTemp();
1283 37723 }
1284 ////END HELPER FUNCTIONS
1285
1286 static int32_t numInstructions = 0; // Used to detect hangs
1287 static bool scriptCanSave = true;
1288
1289 764655445 static ScriptEngineData& get_script_engine_data(ScriptType type, int index)
1290 {
1291
8/8
✓ Branch 0 taken 730548667 times.
✓ Branch 1 taken 34106778 times.
✓ Branch 2 taken 730543381 times.
✓ Branch 3 taken 5286 times.
✓ Branch 4 taken 695544010 times.
✓ Branch 5 taken 34999371 times.
✓ Branch 6 taken 30042 times.
✓ Branch 7 taken 695513968 times.
764655445 if (type == ScriptType::DMap || type == ScriptType::OnMap || type == ScriptType::ScriptedPassiveSubscreen || type == ScriptType::ScriptedActiveSubscreen)
1292 {
1293 // `index` is used for dmapdataref, not for different script engine data.
1294 69141477 index = 0;
1295 69141477 }
1296
2/2
✓ Branch 0 taken 764523417 times.
✓ Branch 1 taken 132028 times.
764655445 if (type == ScriptType::EngineSubscreen)
1297 {
1298 // `index` is used for subscreendataref, not for different script engine data.
1299 132028 index = 0;
1300 132028 }
1301
1302 764655445 return scriptEngineDatas[{type, index}];
1303 }
1304
1305 1242628 static bool script_engine_data_exists(ScriptType type, int index)
1306 {
1307
6/8
✓ Branch 0 taken 1238946 times.
✓ Branch 1 taken 3682 times.
✓ Branch 2 taken 1238942 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 1238942 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1238942 times.
1242628 if (type == ScriptType::DMap || type == ScriptType::OnMap || type == ScriptType::ScriptedPassiveSubscreen || type == ScriptType::ScriptedActiveSubscreen)
1308 {
1309 // `index` is used for dmapdataref, not for different script engine data.
1310 3686 index = 0;
1311 3686 }
1312
1/2
✓ Branch 0 taken 1242628 times.
✗ Branch 1 not taken.
1242628 if (type == ScriptType::EngineSubscreen)
1313 {
1314 // `index` is used for subscreendataref, not for different script engine data.
1315 index = 0;
1316 }
1317
1318 1242628 return scriptEngineDatas.contains({type, index});
1319 }
1320
1321 65 static ScriptEngineData& get_script_engine_data(ScriptType type)
1322 {
1323 65 return get_script_engine_data(type, 0);
1324 }
1325
1326 1149 void FFScript::clear_script_engine_data()
1327 {
1328 1149 scriptEngineDatas.clear();
1329 1149 }
1330
1331 2554501 void FFScript::reset_script_engine_data(ScriptType type, int index)
1332 {
1333 2554501 get_script_engine_data(type, index).reset();
1334 2554501 }
1335
1336 91293 void on_reassign_script_engine_data(ScriptType type, int index)
1337 {
1338 91293 auto& data = get_script_engine_data(type, index);
1339 91293 data.clear_ref();
1340 91293 FFScript::deallocateAllScriptOwned(type, index);
1341 91293 }
1342
1343 2022689 void FFScript::clear_script_engine_data(ScriptType type, int index)
1344 {
1345
4/8
✓ Branch 0 taken 2022689 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2022689 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2022689 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2022689 times.
2022689 if (type == ScriptType::DMap || type == ScriptType::OnMap || type == ScriptType::ScriptedPassiveSubscreen || type == ScriptType::ScriptedActiveSubscreen)
1346 {
1347 // `index` is used for dmapdataref, not for different script engine data.
1348 index = 0;
1349 }
1350
1/2
✓ Branch 0 taken 2022689 times.
✗ Branch 1 not taken.
2022689 if (type == ScriptType::EngineSubscreen)
1351 {
1352 // `index` is used for subscreendataref, not for different script engine data.
1353 index = 0;
1354 }
1355
1356 2022689 auto it = scriptEngineDatas.find({type, index});
1357
2/2
✓ Branch 0 taken 2022445 times.
✓ Branch 1 taken 244 times.
2022689 if (it != scriptEngineDatas.end())
1358 {
1359 244 scriptEngineDatas.erase(it);
1360 244 }
1361 2022689 }
1362
1363 142221 void FFScript::clear_script_engine_data_of_type(ScriptType type)
1364 {
1365 315113286 std::erase_if(scriptEngineDatas, [&](auto& kv) { return kv.first.first == type; });
1366 142221 }
1367
1368 refInfo& FFScript::ref(ScriptType type, int index)
1369 {
1370 return get_script_engine_data(type, index).ref;
1371 }
1372
1373 337 void FFScript::clear_ref(ScriptType type, int index)
1374 {
1375 337 get_script_engine_data(type, index).clear_ref();
1376 337 }
1377
1378 70836197 byte& FFScript::doscript(ScriptType type, int index)
1379 {
1380
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 70836197 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
70836197 if (type == ScriptType::Generic && unsigned(index) < NUMSCRIPTSGENERIC)
1381 return user_genscript::get(index).doscript();
1382 70836197 return get_script_engine_data(type, index).doscript;
1383 70836197 }
1384
1385 540108860 bool& FFScript::waitdraw(ScriptType type, int index)
1386 {
1387 540108860 return get_script_engine_data(type, index).waitdraw;
1388 }
1389
1390 34726996 static void set_current_script_engine_data(ScriptEngineData& data, ScriptType type, int script, int index)
1391 {
1392 34726996 bool got_initialized = false;
1393
1394 34726996 ri = &data.ref;
1395 34726996 stack = &data.stack;
1396 34726996 ret_stack = &data.ret_stack;
1397
1398 // By default, make `Screen->` refer to the top-left screen.
1399 // Will be set to something more specific for relevant script types.
1400 34726996 ri->screenref = cur_screen;
1401
1402
17/18
✗ Branch 0 not taken.
✓ Branch 1 taken 11734893 times.
✓ Branch 2 taken 111621 times.
✓ Branch 3 taken 1355297 times.
✓ Branch 4 taken 522434 times.
✓ Branch 5 taken 9695 times.
✓ Branch 6 taken 15569 times.
✓ Branch 7 taken 12324585 times.
✓ Branch 8 taken 6060449 times.
✓ Branch 9 taken 1542 times.
✓ Branch 10 taken 1330445 times.
✓ Branch 11 taken 126099 times.
✓ Branch 12 taken 909 times.
✓ Branch 13 taken 12244 times.
✓ Branch 14 taken 602613 times.
✓ Branch 15 taken 26364 times.
✓ Branch 16 taken 56336 times.
✓ Branch 17 taken 435901 times.
34726996 switch (type)
1403 {
1404 case ScriptType::FFC:
1405 {
1406 11734893 curscript = ffscripts[script];
1407 11734893 ffcdata* ffc = get_ffc(index);
1408
1409
2/2
✓ Branch 0 taken 11706439 times.
✓ Branch 1 taken 28454 times.
11734893 if (!data.initialized)
1410 {
1411 28454 got_initialized = true;
1412 28454 mapscr* scr = get_scr(ffc->screen_spawned);
1413 28454 memcpy(ri->d, scr->ffcs[index % 128].initd, 8 * sizeof(int32_t));
1414 28454 data.initialized = true;
1415 28454 }
1416
1417
2/2
✓ Branch 0 taken 2204466 times.
✓ Branch 1 taken 9530427 times.
11734893 ri->ffcref = ZScriptVersion::ffcRefIsSpriteId() ? ffc->getUID() : index;
1418 11734893 ri->screenref = ffc->screen_spawned;
1419 }
1420 11734893 break;
1421
1422 case ScriptType::NPC:
1423 {
1424 111621 enemy *spr = (enemy*)guys.getByUID(index);
1425 111621 curscript = guyscripts[script];
1426
1427
2/2
✓ Branch 0 taken 111449 times.
✓ Branch 1 taken 172 times.
111621 if (!data.initialized)
1428 {
1429 172 got_initialized = true;
1430 172 memcpy(ri->d, spr->initD, 8 * sizeof(int32_t));
1431 172 data.initialized = 1;
1432 172 }
1433
1434 111621 ri->npcref = index;
1435 111621 ri->screenref = spr->screen_spawned;
1436 }
1437 111621 break;
1438
1439 case ScriptType::Lwpn:
1440 {
1441 1355297 weapon *spr = (weapon*)Lwpns.getByUID(index);
1442 1355297 curscript = lwpnscripts[script];
1443
1444
2/2
✓ Branch 0 taken 1286496 times.
✓ Branch 1 taken 68801 times.
1355297 if (!data.initialized)
1445 {
1446 68801 got_initialized = true;
1447 68801 memcpy(ri->d, spr->initD, 8 * sizeof(int32_t));
1448 68801 data.initialized = 1;
1449 68801 }
1450
1451 1355297 ri->lwpnref = index;
1452 1355297 ri->screenref = spr->screen_spawned;
1453 }
1454 1355297 break;
1455
1456 case ScriptType::Ewpn:
1457 {
1458 522434 weapon *spr = (weapon*)Ewpns.getByUID(index);
1459 522434 curscript = ewpnscripts[script];
1460
1461
2/2
✓ Branch 0 taken 516683 times.
✓ Branch 1 taken 5751 times.
522434 if (!data.initialized)
1462 {
1463 5751 got_initialized = true;
1464 5751 memcpy(ri->d, spr->initD, 8 * sizeof(int32_t));
1465 5751 data.initialized = 1;
1466 5751 }
1467
1468 522434 ri->ewpnref = index;
1469 522434 ri->screenref = spr->screen_spawned;
1470 }
1471 522434 break;
1472
1473 case ScriptType::ItemSprite:
1474 {
1475 9695 item *spr = (item*)items.getByUID(index);
1476 9695 curscript = itemspritescripts[script];
1477
1478
2/2
✓ Branch 0 taken 9360 times.
✓ Branch 1 taken 335 times.
9695 if (!data.initialized)
1479 {
1480 335 got_initialized = true;
1481 335 memcpy(ri->d, spr->initD, 8 * sizeof(int32_t));
1482 335 data.initialized = 1;
1483 335 }
1484
1485 9695 ri->itemref = index;
1486 9695 ri->screenref = spr->screen_spawned;
1487 }
1488 9695 break;
1489
1490 case ScriptType::Item:
1491 {
1492 15569 int32_t i = index;
1493 15569 int32_t new_i = 0;
1494
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 15232 times.
15569 bool collect = ( ( i < 1 ) || (i == COLLECT_SCRIPT_ITEM_ZERO) );
1495
3/4
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 15232 times.
✓ Branch 2 taken 337 times.
✗ Branch 3 not taken.
15569 new_i = ( collect ) ? (( i != COLLECT_SCRIPT_ITEM_ZERO ) ? (i * -1) : 0) : i;
1496
1497 15569 curscript = itemscripts[script];
1498
1499
2/2
✓ Branch 0 taken 13490 times.
✓ Branch 1 taken 2079 times.
15569 if (!data.initialized)
1500 {
1501 2079 got_initialized = true;
1502
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 1742 times.
2079 memcpy(ri->d, ( collect ) ? itemsbuf[new_i].initiald : itemsbuf[i].initiald, 8 * sizeof(int32_t));
1503 2079 data.initialized = true;
1504 2079 }
1505
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 15232 times.
15569 ri->itemdataref = ( collect ) ? new_i : i; //'this' pointer
1506 }
1507 15569 break;
1508
1509 case ScriptType::Global:
1510 {
1511 12324585 curscript = globalscripts[script];
1512
2/2
✓ Branch 0 taken 12321278 times.
✓ Branch 1 taken 3307 times.
12324585 if (!data.initialized)
1513 {
1514 3307 got_initialized = true;
1515 3307 data.initialized = 1;
1516
1517 // If this compat QR is on, scripts can run before ~Init and set global variables.
1518 // Before overwriting them with 0, get rid of object references held by global variables.
1519
6/6
✓ Branch 0 taken 2673 times.
✓ Branch 1 taken 634 times.
✓ Branch 2 taken 1120 times.
✓ Branch 3 taken 1553 times.
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 1101 times.
3307 if (get_qr(qr_OLD_INIT_SCRIPT_TIMING) && ZScriptVersion::gc() && script == GLOBAL_SCRIPT_INIT)
1520 {
1521
2/2
✓ Branch 0 taken 19456 times.
✓ Branch 1 taken 19 times.
19475 for (int i = 0; i < MAX_SCRIPT_REGISTERS; i++)
1522 19456 script_object_ref_dec(game->global_d[i]);
1523 19 }
1524 3307 }
1525 }
1526 12324585 break;
1527
1528 case ScriptType::Generic:
1529 {
1530 6060449 user_genscript& scr = user_genscript::get(script);
1531 6060449 curscript = genericscripts[script];
1532 6060449 scr.waitevent = false;
1533
2/2
✓ Branch 0 taken 6059741 times.
✓ Branch 1 taken 708 times.
6060449 if(!data.initialized)
1534 {
1535 708 got_initialized = true;
1536 708 scr.initd.copy_to(ri->d, 8);
1537 708 data.initialized = true;
1538 708 }
1539 6060449 ri->genericdataref = script;
1540 }
1541 6060449 break;
1542
1543 case ScriptType::GenericFrozen:
1544 {
1545 1542 user_genscript& scr = user_genscript::get(script);
1546 1542 curscript = genericscripts[script];
1547
2/2
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 10 times.
1542 if(!data.initialized)
1548 {
1549 10 got_initialized = true;
1550 10 scr.initd.copy_to(ri->d, 8);
1551 10 data.initialized = true;
1552 10 }
1553 1542 ri->genericdataref = script;
1554 }
1555 1542 break;
1556
1557 case ScriptType::Hero:
1558 {
1559 1330445 curscript = playerscripts[script];
1560 1330445 ri->screenref = Hero.current_screen;
1561
2/2
✓ Branch 0 taken 1329870 times.
✓ Branch 1 taken 575 times.
1330445 if (!data.initialized)
1562 {
1563 575 got_initialized = true;
1564 575 data.initialized = 1;
1565 575 }
1566 }
1567 1330445 break;
1568
1569 case ScriptType::DMap:
1570 {
1571 126099 curscript = dmapscripts[script];
1572 126099 ri->dmapdataref = index;
1573 //how do we clear initialised on dmap change?
1574
2/2
✓ Branch 0 taken 125971 times.
✓ Branch 1 taken 128 times.
126099 if ( !data.initialized )
1575 {
1576 128 got_initialized = true;
1577
2/2
✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 128 times.
1152 for ( int32_t q = 0; q < 8; q++ )
1578 {
1579 1024 ri->d[q] = DMaps[ri->dmapdataref].initD[q];// * 10000;
1580 1024 }
1581 128 data.initialized = true;
1582 128 }
1583 }
1584 126099 break;
1585
1586 case ScriptType::OnMap:
1587 {
1588 909 curscript = dmapscripts[script];
1589 909 ri->dmapdataref = index;
1590
2/2
✓ Branch 0 taken 902 times.
✓ Branch 1 taken 7 times.
909 if (!data.initialized)
1591 {
1592 7 got_initialized = true;
1593
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 7 times.
63 for ( int32_t q = 0; q < 8; q++ )
1594 {
1595 56 ri->d[q] = DMaps[ri->dmapdataref].onmap_initD[q];
1596 56 }
1597 7 data.initialized = true;
1598 7 }
1599 }
1600 909 break;
1601
1602 case ScriptType::ScriptedActiveSubscreen:
1603 {
1604 12244 curscript = dmapscripts[script];
1605 12244 ri->dmapdataref = index;
1606
2/2
✓ Branch 0 taken 12203 times.
✓ Branch 1 taken 41 times.
12244 if (!data.initialized)
1607 {
1608 41 got_initialized = true;
1609
2/2
✓ Branch 0 taken 328 times.
✓ Branch 1 taken 41 times.
369 for ( int32_t q = 0; q < 8; q++ )
1610 {
1611 328 ri->d[q] = DMaps[ri->dmapdataref].sub_initD[q];
1612 328 }
1613 41 data.initialized = true;
1614 41 }
1615 }
1616 12244 break;
1617
1618 case ScriptType::ScriptedPassiveSubscreen:
1619 {
1620 602613 curscript = dmapscripts[script];
1621 602613 ri->dmapdataref = index;
1622
2/2
✓ Branch 0 taken 602243 times.
✓ Branch 1 taken 370 times.
602613 if (!data.initialized)
1623 {
1624 370 got_initialized = true;
1625
2/2
✓ Branch 0 taken 2960 times.
✓ Branch 1 taken 370 times.
3330 for ( int32_t q = 0; q < 8; q++ )
1626 {
1627 2960 ri->d[q] = DMaps[ri->dmapdataref].sub_initD[q];
1628 2960 }
1629 370 data.initialized = true;
1630 370 }
1631 }
1632 602613 break;
1633 case ScriptType::EngineSubscreen:
1634 {
1635 26364 curscript = subscreenscripts[script];
1636 26364 ri->subscreendataref = get_subref(-1, index);
1637 27092 auto [ptr,_ty] = load_subdata(ri->subscreendataref);
1638
1639
3/4
✓ Branch 0 taken 26364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26273 times.
✓ Branch 3 taken 91 times.
26364 if (ptr && !data.initialized)
1640 {
1641 91 got_initialized = true;
1642
2/2
✓ Branch 0 taken 728 times.
✓ Branch 1 taken 91 times.
819 for ( int32_t q = 0; q < 8; q++ )
1643 {
1644 728 ri->d[q] = ptr->initd[q];
1645 728 }
1646 91 data.initialized = true;
1647 91 }
1648 }
1649 26364 break;
1650
1651 case ScriptType::Screen:
1652 {
1653 56336 curscript = screenscripts[script];
1654
1655
2/2
✓ Branch 0 taken 56192 times.
✓ Branch 1 taken 144 times.
56336 if (!data.initialized)
1656 {
1657 144 got_initialized = true;
1658 144 mapscr* scr = get_scr(index);
1659
2/2
✓ Branch 0 taken 1152 times.
✓ Branch 1 taken 144 times.
1296 for ( int32_t q = 0; q < 8; q++ )
1660 {
1661 1152 ri->d[q] = scr->screeninitd[q];// * 10000;
1662 1152 }
1663 144 data.initialized = true;
1664 144 }
1665
1666 56336 ri->screenref = index;
1667 }
1668 56336 break;
1669
1670 case ScriptType::Combo:
1671 {
1672 435901 curscript = comboscripts[script];
1673
1674 435901 rpos_t rpos = combopos_ref_to_rpos(index);
1675 435901 int32_t lyr = combopos_ref_to_layer(index);
1676 435901 auto rpos_handle = get_rpos_handle(rpos, lyr);
1677 435901 int32_t id = rpos_handle.data();
1678
2/2
✓ Branch 0 taken 421019 times.
✓ Branch 1 taken 14882 times.
435901 if (!data.initialized)
1679 {
1680 14882 got_initialized = true;
1681 14882 memset(ri->d, 0, 8 * sizeof(int32_t));
1682
2/2
✓ Branch 0 taken 119056 times.
✓ Branch 1 taken 14882 times.
133938 for ( int32_t q = 0; q < 8; q++ )
1683 119056 ri->d[q] = combobuf[id].initd[q];
1684 14882 data.initialized = true;
1685 14882 }
1686
1687 435901 ri->combodataref = id; //'this' pointer
1688 435901 ri->comboposref = index; //used for X(), Y(), Layer(), and so forth.
1689 435901 ri->screenref = rpos_handle.screen;
1690 435901 break;
1691 }
1692 }
1693
1694
2/2
✓ Branch 0 taken 34601141 times.
✓ Branch 1 taken 125855 times.
34726996 if (got_initialized)
1695 125855 ri->pc = curscript->pc;
1696 34726996 }
1697
1698 643321730 ffcdata* ResolveFFCWithID(ffc_id_t id)
1699 {
1700
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 643321499 times.
643321730 if (BC::checkFFC(id) != SH::_NoError)
1701 231 return nullptr;
1702
1703 643321499 ffcdata* ffc = get_ffc(id);
1704
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 643321499 times.
643321499 if (!ffc)
1705 scripting_log_error_with_context("Invalid ffc using ID = {}", id);
1706
1707 643321499 return ffc;
1708 643321730 }
1709
1710 646381308 static ffcdata *ResolveFFC(int32_t ffcref)
1711 {
1712
2/2
✓ Branch 0 taken 6428965 times.
✓ Branch 1 taken 639952343 times.
646381308 if (ZScriptVersion::ffcRefIsSpriteId())
1713 6428965 return ResolveSprite<ffcdata>(ffcref, "ffc");
1714
1715 639952343 return ResolveFFCWithID(ffcref);
1716 646381308 }
1717
1718 568164 static mapscr* ResolveMapdataScr(int32_t mapdataref)
1719 {
1720 568164 auto mapdata = decode_mapdata_ref(mapdataref);
1721
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 568164 times.
568164 if (!mapdata.scr)
1722 scripting_log_error_with_context("mapdata id is invalid: {}", mapdataref);
1723 568164 return mapdata.scr;
1724 }
1725
1726 static rpos_handle_t ResolveMapdataPos(int32_t mapdataref, int pos)
1727 {
1728 auto mapdata = decode_mapdata_ref(mapdataref);
1729 if (!mapdata.scr)
1730 {
1731 scripting_log_error_with_context("mapdata id is invalid: {}", mapdataref);
1732 return rpos_handle_t{};
1733 }
1734
1735 return mapdata.resolve_pos(pos);
1736 }
1737
1738 127396572 int mapdata::max_pos()
1739 {
1740
2/2
✓ Branch 0 taken 95534503 times.
✓ Branch 1 taken 31862069 times.
127396572 if (type == mapdata_type::TemporaryCurrentRegion)
1741 95534503 return (int)region_max_rpos;
1742
1743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31862069 times.
31862069 if (type == mapdata_type::TemporaryScrollingRegion)
1744 return (int)scrolling_region.screen_count * 176 - 1;
1745
1746 31862069 return 175;
1747 127396572 }
1748
1749 127396572 rpos_handle_t mapdata::resolve_pos(int pos)
1750 {
1751
3/4
✓ Branch 0 taken 121655856 times.
✓ Branch 1 taken 5740716 times.
✓ Branch 2 taken 121655856 times.
✗ Branch 3 not taken.
127396572 if (!screenscrolling && scrolling())
1752 {
1753 int32_t mapdataref = create_mapdata_temp_ref(type, screen, layer);
1754 scripting_log_error_with_context("mapdata id is invalid: {} - screen is not scrolling right now", mapdataref);
1755 return rpos_handle_t{};
1756 }
1757
1758 // mapdata loaded via `Game->LoadTempScreen(layer)` have access to the entire region.
1759
2/2
✓ Branch 0 taken 95534503 times.
✓ Branch 1 taken 31862069 times.
127396572 if (type == mapdata_type::TemporaryCurrentRegion)
1760 {
1761 95534503 rpos_t rpos = (rpos_t)pos;
1762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95534503 times.
95534503 if (BC::checkComboRpos(rpos) != SH::_NoError)
1763 return rpos_handle_t{};
1764
1765 95534503 return get_rpos_handle(rpos, layer);
1766 }
1767
1768 // mapdata loaded via `Game->LoadScrollingScreen(layer)` have access to the entire scrolling region.
1769
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31862069 times.
31862069 if (type == mapdata_type::TemporaryScrollingRegion)
1770 {
1771 rpos_t rpos = (rpos_t)pos;
1772 rpos_t max = (rpos_t)(scrolling_region.screen_count * 176 - 1);
1773 if (BC::checkBoundsRpos(rpos, (rpos_t)0, max) != SH::_NoError)
1774 return rpos_handle_t{};
1775
1776 int origin_screen = scrolling_region.origin_screen;
1777 int origin_screen_x = origin_screen % 16;
1778 int origin_screen_y = origin_screen / 16;
1779 int scr_index = static_cast<int32_t>(rpos) / 176;
1780 int scr_x = origin_screen_x + scr_index%cur_region.screen_width;
1781 int scr_y = origin_screen_y + scr_index/cur_region.screen_width;
1782 int screen = map_scr_xy_to_index(scr_x, scr_y);
1783 mapscr* scr = FFCore.ScrollingScreensAll[screen * 7 + layer];
1784
1785 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
1786 }
1787
1788 // Otherwise, access is limited to just one screen.
1789
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31862069 times.
31862069 if (BC::checkComboPos(pos) != SH::_NoError)
1790 return rpos_handle_t{};
1791
1792
1/2
✓ Branch 0 taken 31862069 times.
✗ Branch 1 not taken.
31862069 if (type == mapdata_type::CanonicalScreen)
1793 31862069 return {scr, screen, 0, (rpos_t)pos, pos};
1794
1795 if (scrolling())
1796 {
1797 if (!scr->is_valid())
1798 return rpos_handle_t{};
1799
1800 return {scr, screen, layer, (rpos_t)pos, pos};
1801 }
1802
1803 rpos_t rpos = POS_TO_RPOS(pos, screen);
1804 if (BC::checkComboRpos(rpos) != SH::_NoError)
1805 return rpos_handle_t{};
1806
1807 return {scr, screen, layer, rpos, pos};
1808 127396572 }
1809
1810 3023863 ffc_handle_t mapdata::resolve_ffc_handle(int index)
1811 {
1812 3023863 index -= 1;
1813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3023863 times.
3023863 if (BC::checkMapdataFFC(index) != SH::_NoError)
1814 return ffc_handle_t{};
1815
1816 3023863 int screen_index_offset = 0;
1817
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3023863 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3023863 if (current() && layer == 0)
1818 screen_index_offset = get_region_screen_offset(screen);
1819
1820 3023863 return *scr->getFFCHandle(index, screen_index_offset);
1821 3023863 }
1822
1823 ffcdata* mapdata::resolve_ffc(int index)
1824 {
1825 return resolve_ffc_handle(index).ffc;
1826 }
1827
1828 2045 static ffc_handle_t ResolveMapdataFFC(int32_t mapdataref, int index)
1829 {
1830 2045 index -= 1;
1831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2045 times.
2045 if (BC::checkMapdataFFC(index) != SH::_NoError)
1832 return ffc_handle_t{};
1833
1834 2045 auto result = decode_mapdata_ref(mapdataref);
1835
1/2
✓ Branch 0 taken 2045 times.
✗ Branch 1 not taken.
2045 if (!result.scr)
1836 {
1837 scripting_log_error_with_context("mapdata id is invalid: {}", mapdataref);
1838 return ffc_handle_t{};
1839 }
1840
1841 2045 int screen_index_offset = 0;
1842
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2045 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2045 if (result.current() && result.layer == 0)
1843 screen_index_offset = get_region_screen_offset(result.screen);
1844
1845 2045 return *result.scr->getFFCHandle(index, screen_index_offset);
1846 2045 }
1847
1848 int32_t genscript_timing = SCR_TIMING_START_FRAME;
1849 static word max_valid_genscript;
1850
1851 222720 void user_genscript::clear()
1852 {
1853 222720 wait_atleast = true;
1854 222720 waituntil = SCR_TIMING_START_FRAME;
1855 222720 waitevent = false;
1856 222720 exitState = 0;
1857 222720 reloadState = 0;
1858 222720 eventstate = 0;
1859 222720 initd.clear();
1860 222720 data.clear();
1861 222720 quit();
1862 222720 }
1863 635 void user_genscript::launch()
1864 {
1865 635 quit();
1866 635 doscript() = true;
1867 635 wait_atleast = true;
1868 635 waituntil = SCR_TIMING_START_FRAME;
1869 635 waitevent = false;
1870 635 }
1871 223404 void user_genscript::quit()
1872 {
1873
1/2
✓ Branch 0 taken 223404 times.
✗ Branch 1 not taken.
223404 if(indx > -1)
1874 {
1875 223404 FFCore.destroyScriptableObject(ScriptType::Generic, indx);
1876 223404 }
1877 223404 _doscript = false;
1878 223404 }
1879 424851692 byte& user_genscript::doscript()
1880 {
1881 424851692 return _doscript;
1882 }
1883 512 byte const& user_genscript::doscript() const
1884 {
1885 512 return _doscript;
1886 }
1887
1888
1889 447390293 user_genscript& user_genscript::get(int ind)
1890 {
1891
3/4
✓ Branch 0 taken 447389857 times.
✓ Branch 1 taken 436 times.
✓ Branch 2 taken 447389857 times.
✗ Branch 3 not taken.
447390293 if(ind < 1 || ind >= NUMSCRIPTSGENERIC)
1892 436 ind = 0;
1893 447390293 user_scripts[ind].indx = ind;
1894 447390293 return user_scripts[ind];
1895 }
1896
3/4
✓ Branch 0 taken 218624 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 218197 times.
✓ Branch 3 taken 427 times.
218624 user_genscript user_genscript::user_scripts[NUMSCRIPTSGENERIC];
1897
1898 1584 void countGenScripts()
1899 {
1900 1584 max_valid_genscript = 0;
1901
2/2
✓ Branch 0 taken 809424 times.
✓ Branch 1 taken 1584 times.
811008 for(auto q = 1; q < NUMSCRIPTSGENERIC; ++q)
1902 {
1903
3/4
✓ Branch 0 taken 809424 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 804683 times.
✓ Branch 3 taken 4741 times.
809424 if(genericscripts[q] && genericscripts[q]->valid())
1904 4741 max_valid_genscript = q;
1905 809424 }
1906 1584 }
1907 46582 void timeExitAllGenscript(byte exState)
1908 {
1909
2/2
✓ Branch 0 taken 41860 times.
✓ Branch 1 taken 46582 times.
88442 for(auto q = 1; q <= max_valid_genscript; ++q)
1910 41860 user_genscript::get(q).timeExit(exState);
1911 46582 }
1912 500369 void throwGenScriptEvent(int32_t event)
1913 {
1914
2/2
✓ Branch 0 taken 274924 times.
✓ Branch 1 taken 500369 times.
775293 for(auto q = 1; q <= max_valid_genscript; ++q)
1915 {
1916 274924 user_genscript& scr = user_genscript::get(q);
1917
2/2
✓ Branch 0 taken 177127 times.
✓ Branch 1 taken 97797 times.
274924 if(!scr.doscript()) continue;
1918
2/2
✓ Branch 0 taken 151399 times.
✓ Branch 1 taken 25728 times.
177127 if(!genericscripts[q]->valid()) continue;
1919
2/2
✓ Branch 0 taken 50129 times.
✓ Branch 1 taken 101270 times.
151399 if(!scr.waitevent) continue;
1920
2/2
✓ Branch 0 taken 3418 times.
✓ Branch 1 taken 46711 times.
50129 if(scr.eventstate & (1<<event))
1921 {
1922 3418 auto& data = get_script_engine_data(ScriptType::Generic, q);
1923 3418 data.ref.d[rEXP1] = event*10000;
1924 3418 scr.waitevent = false;
1925
1926 //Run the script!
1927 3418 ZScriptVersion::RunScript(ScriptType::Generic, q, q);
1928 3418 }
1929 50129 }
1930 500369 }
1931
1932 226 void load_genscript(const gamedata& gd)
1933 {
1934
2/2
✓ Branch 0 taken 115712 times.
✓ Branch 1 taken 226 times.
115938 for(size_t q = 0; q < NUMSCRIPTSGENERIC; ++q)
1935 {
1936 115712 user_genscript& gen = user_genscript::get(q);
1937 115712 gen.clear();
1938 115712 gen.doscript() = gd.gen_doscript.get(q);
1939 115712 gen.exitState = gd.gen_exitState[q];
1940 115712 gen.reloadState = gd.gen_reloadState[q];
1941 115712 gen.eventstate = gd.gen_eventstate[q];
1942 115712 gen.initd = gd.gen_initd[q];
1943 115712 gen.data = gd.gen_data[q];
1944 115712 }
1945 226 }
1946 209 void load_genscript(const zinitdata& zd)
1947 {
1948
2/2
✓ Branch 0 taken 107008 times.
✓ Branch 1 taken 209 times.
107217 for(size_t q = 0; q < NUMSCRIPTSGENERIC; ++q)
1949 {
1950 107008 user_genscript& gen = user_genscript::get(q);
1951 107008 gen.clear();
1952 107008 gen.doscript() = zd.gen_doscript.get(q);
1953 107008 gen.exitState = zd.gen_exitState[q];
1954 107008 gen.reloadState = zd.gen_reloadState[q];
1955 107008 gen.eventstate = zd.gen_eventstate[q];
1956 107008 gen.initd = zd.gen_initd[q];
1957 107008 gen.data = zd.gen_data[q];
1958 107008 }
1959 209 }
1960
1961 1 void save_genscript(gamedata& gd)
1962 {
1963
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 1 times.
513 for(size_t q = 0; q < NUMSCRIPTSGENERIC; ++q)
1964 {
1965 512 user_genscript const& gen = user_genscript::get(q);
1966 512 gd.gen_doscript.set(q, gen.doscript());
1967 512 gd.gen_exitState[q] = gen.exitState;
1968 512 gd.gen_reloadState[q] = gen.reloadState;
1969 512 gd.gen_eventstate[q] = gen.eventstate;
1970 512 gd.gen_initd[q] = gen.initd;
1971 512 gd.gen_data[q] = gen.data;
1972 512 }
1973 1 }
1974
1975 628513358 void FFScript::runGenericPassiveEngine(int32_t scrtm)
1976 {
1977
2/2
✓ Branch 0 taken 45201089 times.
✓ Branch 1 taken 583312269 times.
628513358 if(!max_valid_genscript) return; //No generic scripts in the quest!
1978 45201089 bool init = (scrtm == SCR_TIMING_INIT);
1979
2/2
✓ Branch 0 taken 125 times.
✓ Branch 1 taken 45200964 times.
45201089 if(!init)
1980 {
1981
2/2
✓ Branch 0 taken 882029 times.
✓ Branch 1 taken 44318935 times.
45200964 if(genscript_timing != scrtm)
1982 {
1983
2/2
✓ Branch 0 taken 3911161 times.
✓ Branch 1 taken 882029 times.
4793190 while(genscript_timing != scrtm)
1984 3911161 runGenericPassiveEngine(genscript_timing);
1985 882029 }
1986 45200964 }
1987
2/2
✓ Branch 0 taken 424303856 times.
✓ Branch 1 taken 45201089 times.
469504945 for(auto q = 1; q <= max_valid_genscript; ++q)
1988 {
1989 424303856 user_genscript& scr = user_genscript::get(q);
1990
2/2
✓ Branch 0 taken 246935354 times.
✓ Branch 1 taken 177368502 times.
424303856 if(!scr.doscript()) continue;
1991
2/2
✓ Branch 0 taken 28899477 times.
✓ Branch 1 taken 218035877 times.
246935354 if(!genericscripts[q]->valid()) continue;
1992
2/2
✓ Branch 0 taken 89025562 times.
✓ Branch 1 taken 129010315 times.
218035877 if(scr.waitevent) continue;
1993
8/8
✓ Branch 0 taken 129010220 times.
✓ Branch 1 taken 95 times.
✓ Branch 2 taken 103609380 times.
✓ Branch 3 taken 25400840 times.
✓ Branch 4 taken 103608796 times.
✓ Branch 5 taken 584 times.
✓ Branch 6 taken 97552442 times.
✓ Branch 7 taken 6056354 times.
129010315 if(!init && (scr.waituntil > scrtm || (!scr.wait_atleast && scr.waituntil != scrtm)))
1994 122953282 continue;
1995
1996 //Run the script!
1997 6057033 ZScriptVersion::RunScript(ScriptType::Generic, q, q);
1998 6057033 }
1999
4/4
✓ Branch 0 taken 45200964 times.
✓ Branch 1 taken 125 times.
✓ Branch 2 taken 44042264 times.
✓ Branch 3 taken 1158700 times.
45201089 if(init || genscript_timing >= SCR_TIMING_END_FRAME)
2000 1158825 genscript_timing = SCR_TIMING_START_FRAME;
2001 44042264 else ++genscript_timing;
2002 628513358 }
2003
2004 14486 void FFScript::initZScriptDMapScripts()
2005 {
2006
1/2
✓ Branch 0 taken 14486 times.
✗ Branch 1 not taken.
14486 scriptEngineDatas[{ScriptType::DMap, 0}] = ScriptEngineData();
2007
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14486 times.
14486 scriptEngineDatas[{ScriptType::ScriptedPassiveSubscreen, 0}] = ScriptEngineData();
2008 14486 }
2009
2010 1438 void FFScript::initZScriptSubscreenScript()
2011 {
2012
1/2
✓ Branch 0 taken 1438 times.
✗ Branch 1 not taken.
1438 scriptEngineDatas[{ScriptType::EngineSubscreen, 0}] = ScriptEngineData();
2013 1438 }
2014 14417 void FFScript::initZScriptScriptedActiveSubscreen()
2015 {
2016
1/2
✓ Branch 0 taken 14417 times.
✗ Branch 1 not taken.
14417 scriptEngineDatas[{ScriptType::ScriptedActiveSubscreen, 0}] = ScriptEngineData();
2017 14417 }
2018
2019 7 void FFScript::initZScriptOnMapScript()
2020 {
2021
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 scriptEngineDatas[{ScriptType::OnMap, 0}] = ScriptEngineData();
2022 7 }
2023
2024 2902 void FFScript::initZScriptHeroScripts()
2025 {
2026
1/2
✓ Branch 0 taken 2902 times.
✗ Branch 1 not taken.
2902 scriptEngineDatas[{ScriptType::Hero, 0}] = ScriptEngineData();
2027 2902 }
2028
2029 2559 void FFScript::initZScriptItemScripts()
2030 {
2031
2/2
✓ Branch 0 taken 655104 times.
✓ Branch 1 taken 2559 times.
657663 for ( int32_t q = 0; q < 256; q++ )
2032 {
2033 655104 auto& data = get_script_engine_data(ScriptType::Item, q);
2034 655104 data.reset();
2035
2/2
✓ Branch 0 taken 655037 times.
✓ Branch 1 taken 67 times.
655104 data.doscript = (itemsbuf[q].flags&item_passive_script) && game->item[q];
2036 655104 }
2037
2038
2/2
✓ Branch 0 taken 655104 times.
✓ Branch 1 taken 2559 times.
657663 for ( int32_t q = -256; q < 0; q++ )
2039 {
2040 655104 auto& data = get_script_engine_data(ScriptType::Item, q);
2041 655104 data.reset();
2042 655104 data.doscript = 0;
2043 655104 }
2044 2559 }
2045
2046 3449923 int get_mouse_state(int index)
2047 {
2048 3449923 int value = 0;
2049
1/2
✓ Branch 0 taken 3449923 times.
✗ Branch 1 not taken.
3449923 if (replay_is_replaying())
2050 {
2051 3449923 value = replay_get_mouse(index);
2052 3449923 }
2053 else if (index == 0)
2054 {
2055 value = script_mouse_x;
2056 }
2057 else if (index == 1)
2058 {
2059 value = script_mouse_y;
2060 }
2061 else if (index == 2)
2062 {
2063 value = script_mouse_z;
2064 }
2065 else if (index == 3)
2066 {
2067 value = script_mouse_b;
2068 }
2069
2070
2/2
✓ Branch 0 taken 3448327 times.
✓ Branch 1 taken 1596 times.
3449923 if (replay_is_recording())
2071 {
2072 1596 replay_set_mouse(index, value);
2073 1596 }
2074
2075 3449923 return value;
2076 }
2077
2078 ///---------------------------------------------//
2079 // Array Helper Functions //
2080 ///---------------------------------------------//
2081
2082 303090259 size_t ArrayH::getSize(const int32_t ptr)
2083 {
2084 303090259 ArrayManager am(ptr);
2085 303090259 return am.size();
2086 }
2087
2088 //Can't you get the std::string and then check its length?
2089 int32_t ArrayH::strlen(const int32_t ptr)
2090 {
2091 ArrayManager am(ptr);
2092 if (am.invalid() || am.size() == 0)
2093 return -1;
2094
2095 word count;
2096 size_t sz = am.size();
2097 for(count = 0; BC::checkUserArrayIndex(count, sz) == _NoError
2098 && am.get(count) != '\0'; count++);
2099
2100 return count;
2101 }
2102
2103 //Returns values of a zscript array as an std::string.
2104 12284615 void ArrayH::getString(const int32_t ptr, string &str, dword num_chars, dword offset)
2105 {
2106 12284615 ArrayManager am(ptr);
2107
2108
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 12284610 times.
12284615 if(am.invalid())
2109 {
2110 5 str.clear();
2111 5 return;
2112 }
2113
2114 12284610 str.clear();
2115 12284610 size_t sz = am.size();
2116
5/6
✓ Branch 0 taken 174004429 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12284610 times.
✓ Branch 3 taken 161719819 times.
✓ Branch 4 taken 12284610 times.
✓ Branch 5 taken 161719819 times.
174004429 for(word i = offset; BC::checkUserArrayIndex(i, sz) == _NoError && am.get(i) != '\0' && num_chars != 0; i++)
2117 {
2118 161719819 int32_t c = am.get(i) / 10000;
2119
1/2
✓ Branch 0 taken 161719819 times.
✗ Branch 1 not taken.
161719819 if(byte(c) != c)
2120 {
2121 Z_scripterrlog("Illegal char value (%d) at position [%d] in string pointer %d\n", c, i, ptr);
2122 Z_scripterrlog("Value of invalid char will overflow.\n");
2123 }
2124 161719819 str += byte(c);
2125 161719819 --num_chars;
2126 161719819 }
2127 12284615 }
2128
2129 //Used for issues where reading the ZScript array floods the console with errors 'Accessing array index [12] size of 12.
2130 //Happens with Quad3D and some other functions, and I have no clue why. -Z ( 28th April, 2019 )
2131 //Like getString but for an array of longs instead of chars. *(arrayPtr is not checked for validity)
2132 void ArrayH::getValues2(const int32_t ptr, int32_t* arrayPtr, dword num_values, dword offset) //a hack -Z
2133 {
2134 ArrayManager am(ptr);
2135
2136 if(am.invalid())
2137 return;
2138
2139 size_t sz = am.size();
2140 for(word i = offset; BC::checkUserArrayIndex(i, sz+1) == _NoError && num_values != 0; i++)
2141 {
2142 arrayPtr[i] = (am.get(i) / 10000);
2143 num_values--;
2144 }
2145 }
2146
2147 //Like getString but for an array of longs instead of chars. *(arrayPtr is not checked for validity)
2148 1080 void ArrayH::getValues(const int32_t ptr, int32_t* arrayPtr, dword num_values, dword offset)
2149 {
2150 1080 ArrayManager am(ptr);
2151
2152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1080 times.
1080 if (am.invalid())
2153 return;
2154 1080 size_t sz = am.size();
2155
4/4
✓ Branch 0 taken 1080 times.
✓ Branch 1 taken 12960 times.
✓ Branch 2 taken 1080 times.
✓ Branch 3 taken 12960 times.
14040 for(word i = offset; num_values != 0 && BC::checkUserArrayIndex(i, sz) == _NoError; i++)
2156 {
2157 12960 arrayPtr[i] = (am.get(i) / 10000);
2158 12960 num_values--;
2159 12960 }
2160 1080 }
2161
2162 2 void ArrayH::copyValues(const int32_t ptr, const int32_t ptr2)
2163 {
2164 2 ArrayManager am1(ptr), am2(ptr2);
2165
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if(am1.invalid() || am2.invalid())
2166 return;
2167
2168 2 int sz = std::min(am1.size(),am2.size());
2169
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 for (int i = 0; i < sz; i++)
2170 {
2171 4 am1.set(i,am2.get(i));
2172 4 }
2173 2 }
2174 //Get element from array
2175 1442197908 INLINE int32_t ArrayH::getElement(const int32_t ptr, int32_t offset, const bool neg)
2176 {
2177 1442197908 ArrayManager am(ptr,neg);
2178 1442197908 return am.get(offset);
2179 }
2180
2181 //Set element in array
2182 676731974 INLINE void ArrayH::setElement(const int32_t ptr, int32_t offset, const int32_t value, const bool neg)
2183 {
2184 676731974 ArrayManager am(ptr,neg);
2185 676731974 am.set(offset,value);
2186 676731974 }
2187
2188 3296918 int32_t ArrayH::setArray(const int32_t ptr, string const& s2, bool resize)
2189 {
2190 3296918 ArrayManager am(ptr);
2191
2192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3296918 times.
3296918 if (am.invalid())
2193 return _InvalidPointer;
2194
2195 size_t i;
2196
2197
3/4
✓ Branch 0 taken 3296918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3268384 times.
✓ Branch 3 taken 28534 times.
3296918 if(am.can_resize() && resize)
2198 28534 am.resize_min(s2.size()+1);
2199
2200 3296918 size_t sz = am.size();
2201
2/2
✓ Branch 0 taken 44035809 times.
✓ Branch 1 taken 3296918 times.
47332727 for(i = 0; i < s2.size(); i++)
2202 {
2203
1/2
✓ Branch 0 taken 44035809 times.
✗ Branch 1 not taken.
44035809 if(i >= sz)
2204 {
2205 am.set(sz-1,'\0');
2206 return _Overflow;
2207 }
2208
2209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44035809 times.
44035809 if(BC::checkUserArrayIndex(i, sz) == _NoError)
2210 44035809 am.set(i,s2[i] * 10000);
2211 44035809 }
2212
2213
1/2
✓ Branch 0 taken 3296918 times.
✗ Branch 1 not taken.
3296918 if(BC::checkUserArrayIndex(i, sz) == _NoError)
2214 3296918 am.set(i,'\0');
2215
2216 3296918 return _NoError;
2217 3296918 }
2218
2219 1182521 void FFScript::release_sprite_owned_objects(int32_t sprite_id)
2220 {
2221 1182521 std::vector<uint32_t> ids_to_clear;
2222
8/14
✓ Branch 0 taken 1182521 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1182521 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1182521 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37081394 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 35898873 times.
✓ Branch 9 taken 1182521 times.
✓ Branch 10 taken 35898873 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 35898873 times.
✗ Branch 13 not taken.
37081394 for (auto& script_object : script_objects | std::views::values)
2223 {
2224
3/4
✓ Branch 0 taken 35898873 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3948 times.
✓ Branch 3 taken 35894925 times.
35898873 if (script_object->sprite_own_clear(sprite_id))
2225 {
2226
1/2
✓ Branch 0 taken 3948 times.
✗ Branch 1 not taken.
3948 ids_to_clear.push_back(script_object->id);
2227
1/2
✓ Branch 0 taken 3948 times.
✗ Branch 1 not taken.
3948 script_object->disown();
2228 3948 }
2229 }
2230
2231
3/4
✓ Branch 0 taken 1182521 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 504268 times.
✓ Branch 3 taken 678253 times.
1182521 if (ZScriptVersion::gc())
2232 {
2233
2/2
✓ Branch 0 taken 3948 times.
✓ Branch 1 taken 504268 times.
508216 for (auto id : ids_to_clear)
2234
1/2
✓ Branch 0 taken 3948 times.
✗ Branch 1 not taken.
3948 script_object_ref_dec(id);
2235 504268 }
2236 else
2237 {
2238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 678253 times.
678253 for (auto id : ids_to_clear)
2239 delete_script_object(id);
2240 }
2241
2242
3/4
✓ Branch 0 taken 1182521 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 503400 times.
✓ Branch 3 taken 679121 times.
1182521 if (!ZScriptVersion::gc_arrays())
2243 {
2244
2/2
✓ Branch 0 taken 2781000495 times.
✓ Branch 1 taken 679121 times.
2781679616 for (int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2245 {
2246
2/4
✓ Branch 0 taken 2781000495 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2781000495 times.
2781000495 if (arrayOwner[i].sprite_own_clear(sprite_id))
2247 FFScript::deallocateArray(i);
2248 2781000495 }
2249 679121 }
2250 1182521 }
2251
2252 // Called when the sprite object is being destroyed.
2253 //
2254 // - clears any object references retained by a sprite via "ownership".
2255 // See the comment above user_abstract_obj::set_owned_by_script for more.
2256 // - clears script engine data
2257 // - invalidates any internal array references that refer to this sprite
2258 1178986 void FFScript::destroySprite(sprite* sprite)
2259 {
2260 DCHECK(sprite->get_scrtype().has_value());
2261 1178986 ScriptType scriptType = *sprite->get_scrtype();
2262 1178986 int32_t uid = sprite->getUID();
2263 1178986 FFCore.release_sprite_owned_objects(uid);
2264 1178986 FFCore.deallocateAllScriptOwned(scriptType, uid);
2265 1178986 FFCore.reset_script_engine_data(scriptType, uid);
2266 1178986 expire_internal_script_arrays(scriptType, uid);
2267 1178986 }
2268
2269 // Same as "onDestroySprite", but for non-sprite things.
2270 1354082 void FFScript::destroyScriptableObject(ScriptType scriptType, const int32_t UID)
2271 {
2272 1354082 FFCore.deallocateAllScriptOwned(scriptType, UID);
2273 1354082 FFCore.reset_script_engine_data(scriptType, UID);
2274 1354082 expire_internal_script_arrays(scriptType, UID);
2275 1354082 }
2276
2277 37530 void FFScript::destroyScriptableObjectsOfType(ScriptType scriptType)
2278 {
2279 37530 FFCore.deallocateAllScriptOwnedOfType(scriptType);
2280 37530 FFCore.clear_script_engine_data_of_type(scriptType);
2281 37530 expire_internal_script_arrays(scriptType);
2282 37530 }
2283
2284 2736004 void FFScript::deallocateAllScriptOwned(ScriptType scriptType, const int32_t UID)
2285 {
2286 2736004 std::vector<uint32_t> ids_to_clear;
2287
8/14
✓ Branch 0 taken 2736004 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2736004 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2736004 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 73891279 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 71155275 times.
✓ Branch 9 taken 2736004 times.
✓ Branch 10 taken 71155275 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 71155275 times.
✗ Branch 13 not taken.
73891279 for (auto& script_object : script_objects | std::views::values)
2288 {
2289
3/4
✓ Branch 0 taken 71155275 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 149 times.
✓ Branch 3 taken 71155126 times.
71155275 if (script_object->script_own_clear(scriptType, UID))
2290 {
2291
1/2
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
149 ids_to_clear.push_back(script_object->id);
2292
1/2
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
149 script_object->disown();
2293 149 }
2294 }
2295
2296
6/8
✓ Branch 0 taken 2736004 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1242628 times.
✓ Branch 3 taken 1493376 times.
✓ Branch 4 taken 1242628 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 637858 times.
✓ Branch 7 taken 604770 times.
2736004 if (ZScriptVersion::gc() && script_engine_data_exists(scriptType, UID))
2297 {
2298
1/2
✓ Branch 0 taken 637858 times.
✗ Branch 1 not taken.
637858 auto& data = get_script_engine_data(scriptType, UID);
2299
2/2
✓ Branch 0 taken 615 times.
✓ Branch 1 taken 637858 times.
638473 for (uint32_t offset : data.ref.stack_pos_is_object)
2300 {
2301 615 uint32_t id = data.stack[offset];
2302
1/2
✓ Branch 0 taken 615 times.
✗ Branch 1 not taken.
615 ids_to_clear.push_back(id);
2303 }
2304 637858 data.ref.stack_pos_is_object.clear();
2305 637858 }
2306
2307
3/4
✓ Branch 0 taken 2736004 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1242628 times.
✓ Branch 3 taken 1493376 times.
2736004 if (ZScriptVersion::gc())
2308 {
2309
2/2
✓ Branch 0 taken 615 times.
✓ Branch 1 taken 1242628 times.
1243243 for (auto id : ids_to_clear)
2310
1/2
✓ Branch 0 taken 615 times.
✗ Branch 1 not taken.
615 script_object_ref_dec(id);
2311 1242628 }
2312 else
2313 {
2314
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 1493376 times.
1493525 for (auto id : ids_to_clear)
2315
1/2
✓ Branch 0 taken 149 times.
✗ Branch 1 not taken.
149 delete_script_object(id);
2316 }
2317
2318
3/4
✓ Branch 0 taken 2736004 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1204702 times.
✓ Branch 3 taken 1531302 times.
2736004 if (!ZScriptVersion::gc_arrays())
2319 {
2320
2/2
✓ Branch 0 taken 6270681690 times.
✓ Branch 1 taken 1531302 times.
6272212992 for(int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2321 {
2322
3/4
✓ Branch 0 taken 6270681690 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30496 times.
✓ Branch 3 taken 6270651194 times.
6270681690 if(arrayOwner[i].script_own_clear(scriptType,UID))
2323
1/2
✓ Branch 0 taken 30496 times.
✗ Branch 1 not taken.
30496 deallocateArray(i);
2324 6270681690 }
2325 1531302 }
2326 2736004 }
2327
2328 142221 void FFScript::deallocateAllScriptOwnedOfType(ScriptType scriptType)
2329 {
2330 142221 std::vector<uint32_t> ids_to_clear;
2331
8/14
✓ Branch 0 taken 142221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 142221 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 142221 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 902332 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 760111 times.
✓ Branch 9 taken 142221 times.
✓ Branch 10 taken 760111 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 760111 times.
✗ Branch 13 not taken.
902332 for (auto& script_object : script_objects | std::views::values)
2332 {
2333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 760111 times.
760111 if (script_object->owned_type == scriptType)
2334 {
2335 ids_to_clear.push_back(script_object->id);
2336 script_object->disown();
2337 }
2338 }
2339
2340
3/4
✓ Branch 0 taken 142221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73280 times.
✓ Branch 3 taken 68941 times.
142221 if (ZScriptVersion::gc())
2341 {
2342
2/2
✓ Branch 0 taken 169515333 times.
✓ Branch 1 taken 73280 times.
169595121 for (auto& [key, data] : scriptEngineDatas)
2343 {
2344
2/2
✓ Branch 0 taken 169508825 times.
✓ Branch 1 taken 6508 times.
169515333 if (key.first != scriptType)
2345 169508825 continue;
2346
2347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6508 times.
6508 for (uint32_t offset : data.ref.stack_pos_is_object)
2348 {
2349 uint32_t id = data.stack[offset];
2350 ids_to_clear.push_back(id);
2351 }
2352 6508 data.ref.stack_pos_is_object.clear();
2353 }
2354
2355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73280 times.
73280 for (auto id : ids_to_clear)
2356 script_object_ref_dec(id);
2357 73280 }
2358 else
2359 {
2360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68941 times.
68941 for (auto id : ids_to_clear)
2361 delete_script_object(id);
2362 }
2363
2364
3/4
✓ Branch 0 taken 142221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72879 times.
✓ Branch 3 taken 69342 times.
142221 if (!ZScriptVersion::gc_arrays())
2365 {
2366
2/2
✓ Branch 0 taken 283955490 times.
✓ Branch 1 taken 69342 times.
284024832 for(int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2367 {
2368
1/2
✓ Branch 0 taken 283955490 times.
✗ Branch 1 not taken.
283955490 if(arrayOwner[i].owned_type == scriptType)
2369 deallocateArray(i);
2370 283955490 }
2371 69342 }
2372 142221 }
2373
2374 // Only called when resetting the engine. Don't keep anything.
2375 400 void FFScript::deallocateAllScriptOwned()
2376 {
2377 400 script_object_ids_by_type.clear();
2378 400 script_objects.clear();
2379 400 next_script_object_id_freelist.clear();
2380
2381
2/2
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 211 times.
400 if (!ZScriptVersion::gc_arrays())
2382 {
2383
2/2
✓ Branch 0 taken 864045 times.
✓ Branch 1 taken 211 times.
864256 for(int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2384 {
2385
2/2
✓ Branch 0 taken 863871 times.
✓ Branch 1 taken 174 times.
864045 if(localRAM[i].Valid())
2386 {
2387 // Unowned arrays are ALSO deallocated!
2388 174 arrayOwner[i].clear();
2389 174 localRAM[i].Clear();
2390 174 }
2391 864045 }
2392 211 }
2393 400 }
2394
2395 714 void FFScript::deallocateAllScriptOwnedCont()
2396 {
2397 714 std::vector<uint32_t> ids_to_clear;
2398
8/14
✓ Branch 0 taken 714 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 714 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 714 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5026 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4312 times.
✓ Branch 9 taken 714 times.
✓ Branch 10 taken 4312 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 4312 times.
✗ Branch 13 not taken.
5026 for (auto& script_object : script_objects | std::views::values)
2399 {
2400
2/4
✓ Branch 0 taken 4312 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4312 times.
4312 if (script_object->script_own_clear_cont())
2401 {
2402 ids_to_clear.push_back(script_object->id);
2403 script_object->disown();
2404 }
2405 }
2406
2407
3/4
✓ Branch 0 taken 714 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 323 times.
✓ Branch 3 taken 391 times.
714 if (ZScriptVersion::gc())
2408 {
2409
2/2
✓ Branch 0 taken 540096 times.
✓ Branch 1 taken 323 times.
1080516 for (auto& [key, data] : scriptEngineDatas)
2410 {
2411
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 540096 times.
540097 for (uint32_t offset : data.ref.stack_pos_is_object)
2412 {
2413 1 uint32_t id = data.stack[offset];
2414
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ids_to_clear.push_back(id);
2415 }
2416 540096 data.ref.stack_pos_is_object.clear();
2417 }
2418
2419
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 323 times.
324 for (auto id : ids_to_clear)
2420
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 script_object_ref_dec(id);
2421 323 }
2422 else
2423 {
2424
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 391 times.
391 for (auto id : ids_to_clear)
2425 delete_script_object(id);
2426 }
2427
2428
3/4
✓ Branch 0 taken 714 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 323 times.
✓ Branch 3 taken 391 times.
714 if (!ZScriptVersion::gc_arrays())
2429 {
2430 //No QR check here- always deallocate on quest exit.
2431
2/2
✓ Branch 0 taken 1601145 times.
✓ Branch 1 taken 391 times.
1601536 for(int32_t i = 1; i < NUM_ZSCRIPT_ARRAYS; i++)
2432 {
2433
3/4
✓ Branch 0 taken 1601145 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3165 times.
✓ Branch 3 taken 1597980 times.
1601145 if(localRAM[i].Valid())
2434 {
2435
2/4
✓ Branch 0 taken 3165 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3165 times.
✗ Branch 3 not taken.
3165 if(arrayOwner[i].script_own_clear_cont())
2436
1/2
✓ Branch 0 taken 3165 times.
✗ Branch 1 not taken.
3165 deallocateArray(i);
2437 3165 }
2438 1601145 }
2439 391 }
2440 714 }
2441
2442 10585196 weapon *checkLWpn(int32_t uid)
2443 {
2444 10585196 return ResolveSprite<weapon>(uid, "lweapon");
2445 }
2446
2447 20622405 weapon *checkEWpn(int32_t uid)
2448 {
2449 20622405 return ResolveSprite<weapon>(uid, "eweapon");
2450 }
2451
2452 29700482 weapon *checkWpn(int32_t uid)
2453 {
2454 29700482 return ResolveSprite<weapon>(uid, "weapon");
2455 }
2456
2457 10426918 user_genscript *checkGenericScr(int32_t ref)
2458 {
2459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10426918 times.
10426918 if (BC::checkBounds(ref, 1, NUMSCRIPTSGENERIC-1) != SH::_NoError)
2460 return NULL;
2461
2462 10426918 return &user_genscript::get(ref);
2463 10426918 }
2464 extern portal mirror_portal;
2465 portal *checkPortal(int32_t ref, bool skiperr = false)
2466 {
2467 if(ref == -1)
2468 return &mirror_portal;
2469
2470 portal* p = (portal*)portals.getByUID(ref);
2471 if(!p)
2472 {
2473 if(!skiperr)
2474 scripting_log_error_with_context("Invalid portal pointer: {}", ref);
2475 return nullptr;
2476 }
2477 return p;
2478 }
2479
2480 savedportal *checkSavedPortal(int32_t ref, bool skiperr = false)
2481 {
2482 savedportal* sp = game->getSavedPortal(ref);
2483 if(!sp)
2484 {
2485 if(!skiperr)
2486 scripting_log_error_with_context("Invalid savedportal pointer: {}", ref);
2487 return nullptr;
2488 }
2489 return sp;
2490 }
2491 int32_t getPortalFromSaved(savedportal* p)
2492 {
2493 if(p == &(game->saved_mirror_portal))
2494 return -1;
2495 portal* prtl = nullptr;
2496 portals.forEach([&](sprite& spr)
2497 {
2498 portal* tmp = (portal*)&spr;
2499 if(p->getUID() == tmp->saved_data)
2500 {
2501 prtl = tmp;
2502 return true;
2503 }
2504 return false;
2505 });
2506 return prtl ? prtl->getUID() : 0;
2507 }
2508
2509 static user_stack *checkStack(uint32_t id, bool skipError = false)
2510 {
2511 return user_stacks.check(id, skipError);
2512 }
2513
2514 521996 static user_rng *checkRNG(uint32_t id, bool skipError = false)
2515 {
2516 // A null RNG pointer is special-case, access engine rng.
2517
2/2
✓ Branch 0 taken 520473 times.
✓ Branch 1 taken 1523 times.
521996 if (id == 0) return &nulrng;
2518 1523 return user_rngs.check(id, skipError);
2519 521996 }
2520
2521 17949 user_paldata* checkPalData(int32_t ref, bool skipError)
2522 {
2523 17949 return user_paldatas.check(ref, skipError);
2524 }
2525
2526 129247 newcombo* checkCombo(int32_t ref, bool skipError)
2527 {
2528
2/4
✓ Branch 0 taken 129247 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 129247 times.
129247 if (ref < 0 || ref > (MAXCOMBOS-1) )
2529 {
2530 scripting_log_error_with_context("Invalid combodata ID: {}", ref);
2531 return nullptr;
2532 }
2533
2534 129247 return &combobuf[ref];
2535 129247 }
2536
2537 // TODO: replace with checkCombo.
2538 6241321 static bool checkComboRef()
2539 {
2540
2/4
✓ Branch 0 taken 6241321 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6241321 times.
6241321 if (GET_REF(combodataref) < 0 || GET_REF(combodataref) > (MAXCOMBOS-1))
2541 {
2542 scripting_log_error_with_context("Invalid combodata ID: {}", GET_REF(combodataref));
2543 return false;
2544 }
2545
2546 6241321 return true;
2547 6241321 }
2548
2549 newcombo* checkComboFromTriggerRef(dword ref)
2550 {
2551 ref = get_combo_from_trigger_ref(ref);
2552 return checkCombo(ref);
2553 }
2554
2555 381675 dmap* checkDmap(int32_t ref)
2556 {
2557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 381675 times.
381675 if (BC::checkDMapID(ref) != SH::_NoError)
2558 return nullptr;
2559
2560 381675 return &DMaps[ref];
2561 381675 }
2562
2563 23489683 ffcdata* checkFFC(int32_t ref)
2564 {
2565 23489683 return ResolveFFC(ref);
2566 }
2567
2568 46968317 enemy* checkNPC(int32_t ref)
2569 {
2570 46968317 return ResolveNpc(ref);
2571 }
2572
2573 guydata* checkNPCData(int32_t ref)
2574 {
2575 if (ref >= 0 && ref < MAXNPCS)
2576 return &guysbuf[ref];
2577
2578 scripting_log_error_with_context("Invalid {} using UID = {}", "npcdata", ref);
2579 return nullptr;
2580 }
2581
2582 // TODO: replace with checkNPCData.
2583 6366 static bool checkNPCDataRef()
2584 {
2585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6366 times.
6366 if( (unsigned) GET_REF(npcdataref) > (MAXNPCS-1) )
2586 {
2587 scripting_log_error_with_context("Invalid npcdata ID: {}", GET_REF(npcdataref));
2588 return false;
2589 }
2590
2591 6366 return true;
2592 6366 }
2593
2594 2240371 item* checkItem(int32_t ref)
2595 {
2596 2240371 return ResolveItemSprite(ref);
2597 }
2598
2599 167 itemdata* checkItemData(int32_t ref)
2600 {
2601
2/4
✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 167 times.
✗ Branch 3 not taken.
167 if (ref >= 0 && ref < MAXITEMS)
2602 167 return &itemsbuf[ref];
2603
2604 scripting_log_error_with_context("Invalid {} using UID = {}", "itemdata", ref);
2605 return nullptr;
2606 167 }
2607
2608 131061686 mapdata* checkMapData(int32_t ref)
2609 {
2610 static mapdata last_result;
2611
2612 131061686 last_result = decode_mapdata_ref(ref);
2613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131061686 times.
131061686 if (!last_result.scr)
2614 {
2615 scripting_log_error_with_context("Invalid {} using UID = {}", "mapdata", ref);
2616 return nullptr;
2617 }
2618
2619 131061686 return &last_result;
2620 131061686 }
2621
2622 977428 mapscr* checkMapDataScr(int32_t ref)
2623 {
2624 977428 return decode_mapdata_ref(ref).scr;
2625 }
2626
2627 26487048 screendata* checkScreen(int32_t ref)
2628 {
2629 26487048 return (screendata*)get_scr_maybe(cur_map, ref);
2630 }
2631
2632 bottletype* checkBottleData(int32_t ref, bool skipError)
2633 {
2634 if(ref > 0 && ref <= 64)
2635 {
2636 return &QMisc.bottle_types[ref-1];
2637 }
2638 if(skipError) return NULL;
2639
2640 scripting_log_error_with_context("Invalid {} using UID = {}", "bottledata", ref);
2641 return NULL;
2642 }
2643
2644 bottleshoptype *checkBottleShopData(int32_t ref, bool skipError)
2645 {
2646 if(ref > 0 && ref <= 256)
2647 {
2648 return &QMisc.bottle_shop_types[ref-1];
2649 }
2650 if(skipError) return NULL;
2651
2652 scripting_log_error_with_context("Invalid {} using UID = {}", "bottleshopdata", ref);
2653 return NULL;
2654 }
2655
2656 item_drop_object *checkDropSetData(int32_t ref)
2657 {
2658 if(ref > 0 && ref < MAXITEMDROPSETS)
2659 return &item_drop_sets[ref];
2660
2661 scripting_log_error_with_context("Invalid {} using UID = {}", "dropsetdata", ref);
2662 return NULL;
2663 }
2664
2665 5603 wpndata *checkSpriteData(int32_t ref)
2666 {
2667
2/4
✓ Branch 0 taken 5603 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5603 times.
✗ Branch 3 not taken.
5603 if(ref > 0 && ref < MAXWPNS)
2668 5603 return &wpnsbuf[ref];
2669
2670 scripting_log_error_with_context("Invalid {} using UID = {}", "spritedata", ref);
2671 return NULL;
2672 5603 }
2673
2674 MsgStr *checkMessageData(int32_t ref)
2675 {
2676 if(ref > 0 && ref < msg_strings_size)
2677 return &MsgStrings[ref];
2678
2679 scripting_log_error_with_context("Invalid {} using UID = {}", "messagedata", ref);
2680 return NULL;
2681 }
2682
2683 combo_trigger* checkComboTrigger(dword ref)
2684 {
2685 return get_combo_trigger(ref);
2686 }
2687
2688 67027245 user_bitmap *checkBitmap(int32_t ref, bool req_valid = false, bool skipError = false)
2689 {
2690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67027245 times.
67027245 switch (ref - 10)
2691 {
2692 case rtSCREEN:
2693 case rtBMP0:
2694 case rtBMP1:
2695 case rtBMP2:
2696 case rtBMP3:
2697 case rtBMP4:
2698 case rtBMP5:
2699 case rtBMP6:
2700 zprint2("Internal error: 'checkBitmap()' recieved ref pointing to system bitmap!\n");
2701 zprint2("Please report this as a bug!\n");
2702
2703 if(skipError) return NULL;
2704
2705 scripting_log_error_with_context("Tried to reference a non-existent bitmap with UID = {}", ref);
2706 return NULL;
2707
2708 default:
2709 {
2710 67027245 user_bitmap* b = user_bitmaps.check(ref, skipError);
2711
4/6
✓ Branch 0 taken 66996830 times.
✓ Branch 1 taken 30415 times.
✓ Branch 2 taken 66996830 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 66996830 times.
✗ Branch 5 not taken.
67027245 if (req_valid && (!b || !b->u_bmp))
2712 {
2713 if (skipError) return NULL;
2714
2715 scripting_log_error_with_context("Tried to reference an invalid user bitmap with UID = {}.", ref);
2716 Z_scripterrlog("Did you forget to create the bitmap with `new bitmap()` or `->Create()`?.\n");
2717 return NULL;
2718 }
2719 67027245 return b;
2720 }
2721 }
2722 67027245 }
2723
2724 extern const std::string subscr_names[sstMAX];
2725 static std::string subscr_type_names(std::set<int> const& req_tys)
2726 {
2727 ostringstream oss;
2728 bool first = true;
2729 for (auto req_ty : req_tys)
2730 {
2731 if (first)
2732 first = false;
2733 else oss << ", ";
2734 oss << "'" << subscr_names[req_ty] << "'";
2735 }
2736 return oss.str();
2737 }
2738 159701 ZCSubscreen *checkSubData(int32_t ref, std::set<int> const& req_tys)
2739 {
2740 324499 auto [ptr,ty] = load_subdata(ref);
2741
1/2
✓ Branch 0 taken 159701 times.
✗ Branch 1 not taken.
159701 if(ptr)
2742 {
2743
3/4
✓ Branch 0 taken 154604 times.
✓ Branch 1 taken 5097 times.
✓ Branch 2 taken 159701 times.
✗ Branch 3 not taken.
159701 if(req_tys.empty() || req_tys.contains(ty))
2744 159701 return ptr;
2745 else
2746 {
2747 scripting_log_error_with_context("Wrong type of SubscreenData accessed! Expecting type [{}], but found '{}'",
2748 subscr_type_names(req_tys), subscr_names[ty]);
2749 }
2750 }
2751 else scripting_log_error_with_context("Script attempted to reference a nonexistent SubscreenData!");
2752
2753 scripting_log_error_with_context("You were trying to reference an invalid SubscreenData with UID = {}", ref);
2754 return NULL;
2755 159701 }
2756
2757 56028 SubscrPage *checkSubPage(int32_t ref, std::set<int> const& req_tys)
2758 {
2759 126926 auto [ptr,ty] = load_subpage(ref);
2760
1/2
✓ Branch 0 taken 56028 times.
✗ Branch 1 not taken.
56028 if(ptr)
2761 {
2762
3/4
✓ Branch 0 taken 41158 times.
✓ Branch 1 taken 14870 times.
✓ Branch 2 taken 56028 times.
✗ Branch 3 not taken.
56028 if(req_tys.empty() || req_tys.contains(ty))
2763 56028 return ptr;
2764 else
2765 {
2766 scripting_log_error_with_context("Wrong type of Subscreen accessed! Expecting type [{}], but found '{}'",
2767 subscr_type_names(req_tys), subscr_names[ty]);
2768 }
2769 }
2770 else scripting_log_error_with_context("Script attempted to reference a nonexistent SubscreenPage!");
2771
2772 scripting_log_error_with_context("You were trying to reference an invalid SubscreenPage with UID = {}", ref);
2773 return NULL;
2774 56028 }
2775
2776 103742 SubscrWidget *checkSubWidg(int32_t ref, std::set<int> const& req_sub_tys, int req_widg_ty)
2777 {
2778 207484 auto [ptr,ty] = load_subwidg(ref);
2779
1/2
✓ Branch 0 taken 103742 times.
✗ Branch 1 not taken.
103742 if(ptr)
2780 {
2781
2/4
✓ Branch 0 taken 103742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103742 times.
✗ Branch 3 not taken.
103742 if(req_sub_tys.empty() || req_sub_tys.contains(ty))
2782 {
2783
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 103742 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
103742 if(req_widg_ty < 0 || req_widg_ty == ptr->getType())
2784 103742 return ptr;
2785 else
2786 {
2787 auto listdata = GUI::ZCListData::subscr_widgets();
2788 scripting_log_error_with_context("Wrong type of SubscreenWidget accessed! Expecting type '{}', but found '{}'",
2789 listdata.findText(req_widg_ty), listdata.findText(ptr->getType()));
2790 }
2791 }
2792 else
2793 {
2794 scripting_log_error_with_context("Wrong type of Subscreen accessed! Expecting subscreen type '{}', but found '{}'",
2795 subscr_type_names(req_sub_tys), subscr_names[ty]);
2796 }
2797 }
2798 else scripting_log_error_with_context("Script attempted to reference a nonexistent SubscreenWidget!");
2799
2800 scripting_log_error_with_context("You were trying to reference an invalid SubscreenWidget with UID = {}", ref);
2801 return NULL;
2802 103742 }
2803
2804 static void bad_subwidg_type(bool func, byte type)
2805 {
2806 auto tyname = type < widgMAX ? subwidg_internal_names[type].c_str() : "";
2807 scripting_log_error_with_context("Widget type {} '{}' does not have this {}!",
2808 type, tyname, func ? "function" : "value");
2809 }
2810
2811 3 int32_t item_flag(item_flags flag)
2812 {
2813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
2814 {
2815 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
2816 return 0;
2817 }
2818 3 return (itemsbuf[GET_REF(itemdataref)].flags & flag) ? 10000 : 0;
2819 3 }
2820 void item_flag(item_flags flag, bool val)
2821 {
2822 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
2823 {
2824 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
2825 return;
2826 }
2827 SETFLAG(itemsbuf[GET_REF(itemdataref)].flags, flag, val);
2828 }
2829
2830 bool scripting_use_8bit_colors;
2831 int scripting_max_color_val;
2832
2833 440756 static int scripting_read_pal_color(int c)
2834 {
2835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440756 times.
440756 return scripting_use_8bit_colors ? c : c / 4;
2836 }
2837
2838 139440 static int scripting_write_pal_color(int c)
2839 {
2840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139440 times.
139440 return scripting_use_8bit_colors ? c : _rgb_scale_6[c];
2841 }
2842
2843 10405 void apply_qr_rule(int qr_id)
2844 {
2845 10405 bool value = get_qr(qr_id);
2846
8/8
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 1149 times.
✓ Branch 2 taken 2355 times.
✓ Branch 3 taken 1149 times.
✓ Branch 4 taken 1149 times.
✓ Branch 5 taken 1149 times.
✓ Branch 6 taken 1149 times.
✓ Branch 7 taken 1156 times.
10405 switch (qr_id)
2847 {
2848 case qr_LTTPWALK:
2849 1149 Hero.setDiagMove(value?1:0);
2850 1149 break;
2851 case qr_LTTPCOLLISION:
2852 1149 Hero.setBigHitbox(value?1:0);
2853 1149 break;
2854 case qr_ZS_NO_NEG_ARRAY:
2855 1149 can_neg_array = !value;
2856 1149 break;
2857 case qr_SCRIPTS_6_BIT_COLOR:
2858 {
2859
2/2
✓ Branch 0 taken 1147 times.
✓ Branch 1 taken 2 times.
1149 if (value)
2860 {
2861 1147 scripting_use_8bit_colors = false;
2862 1147 scripting_max_color_val = 63;
2863 1147 }
2864 else
2865 {
2866 2 scripting_use_8bit_colors = true;
2867 2 scripting_max_color_val = 255;
2868 }
2869 1149 break;
2870 }
2871 case qr_HIDE_BOTTOM_8_PIXELS:
2872 {
2873 1156 updateShowBottomPixels();
2874 1156 break;
2875 }
2876 case qr_COOLSCROLL:
2877 case qr_FADEBLACKWIPE:
2878 case qr_OVALWIPE:
2879 case qr_SMASWIPE:
2880 case qr_TRIANGLEWIPE:
2881 {
2882 1149 COOLSCROLL =
2883 3447 (get_qr(qr_COOLSCROLL)!=0 ? 1 : 0) |
2884 2298 (get_qr(qr_OVALWIPE)!=0 ? 2 : 0) |
2885 2298 (get_qr(qr_TRIANGLEWIPE)!=0 ? 4 : 0) |
2886 2298 (get_qr(qr_SMASWIPE)!=0 ? 8 : 0) |
2887 1149 (get_qr(qr_FADEBLACKWIPE)!=0 ? 16 : 0);
2888 1149 break;
2889 }
2890 case qr_BSZELDA:
2891 {
2892 1149 BSZ = value;
2893 1149 break;
2894 }
2895 }
2896 10405 }
2897
2898 1149 static void apply_qr_rules()
2899 {
2900 1149 apply_qr_rule(qr_BSZELDA);
2901 1149 apply_qr_rule(qr_COOLSCROLL);
2902 1149 apply_qr_rule(qr_HIDE_BOTTOM_8_PIXELS);
2903 1149 apply_qr_rule(qr_LTTPCOLLISION);
2904 1149 apply_qr_rule(qr_LTTPWALK);
2905 1149 apply_qr_rule(qr_SCRIPTS_6_BIT_COLOR);
2906 1149 apply_qr_rule(qr_ZS_NO_NEG_ARRAY);
2907 1149 }
2908
2909 //Forward decl
2910 int32_t do_msgheight(int32_t msg);
2911 int32_t do_msgwidth(int32_t msg);
2912 //
2913
2914 template <typename T, size_t N>
2915 static int read_array(const T(&arr)[N], int index)
2916 {
2917 if (BC::checkIndex(index, 0, N - 1) != SH::_NoError)
2918 return 0;
2919
2920 return arr[index];
2921 }
2922
2923 template <typename T, size_t N>
2924 static bool write_array(T(&arr)[N], int index, T value)
2925 {
2926 if (BC::checkIndex(index, 0, N - 1) != SH::_NoError)
2927 return false;
2928
2929 arr[index] = value;
2930 return true;
2931 }
2932
2933 284185699 static int get_ref(int arg)
2934 {
2935
15/35
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 129247 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 380040 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 27478207 times.
✓ Branch 12 taken 23489683 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 10419017 times.
✓ Branch 15 taken 169801 times.
✓ Branch 16 taken 167 times.
✓ Branch 17 taken 2222271 times.
✓ Branch 18 taken 131480945 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 46964382 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 29098432 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 12300950 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 49980 times.
✓ Branch 32 taken 2475 times.
✓ Branch 33 taken 102 times.
✗ Branch 34 not taken.
284185699 switch (arg)
2936 {
2937 case CLASS_THISKEY: return ri->thiskey;
2938 case CLASS_THISKEY2: return ri->thiskey2;
2939 case REFBITMAP: return ri->bitmapref;
2940 case REFBOTTLESHOP: return ri->bottleshopref;
2941 case REFBOTTLETYPE: return ri->bottletyperef;
2942 129247 case REFCOMBODATA: return ri->combodataref;
2943 case REFCOMBOTRIGGER: return ri->combotriggerref;
2944 case REFDIRECTORY: return ri->directoryref;
2945 380040 case REFDMAPDATA: return ri->dmapdataref;
2946 case REFDROPSETDATA: return ri->dropsetdataref;
2947 27478207 case REFEWPN: return ri->ewpnref;
2948 23489683 case REFFFC: return ri->ffcref;
2949 case REFFILE: return ri->fileref;
2950 10419017 case REFGENERICDATA: return ri->genericdataref;
2951 169801 case REFITEM: return ri->itemref;
2952 167 case REFITEMDATA: return ri->itemdataref;
2953 2222271 case REFLWPN: return ri->lwpnref;
2954 131480945 case REFMAPDATA: return ri->mapdataref;
2955 case REFMSGDATA: return ri->msgdataref;
2956 46964382 case REFNPC: return ri->npcref;
2957 case REFNPCDATA: return ri->npcdataref;
2958 case REFPALDATA: return ri->paldataref;
2959 case REFPORTAL: return ri->portalref;
2960 case REFRNG: return ri->rngref;
2961 case REFSAVPORTAL: return ri->savportalref;
2962 29098432 case REFSCREEN: return ri->screenref;
2963 case REFSHOPDATA: return ri->shopdataref;
2964 12300950 case REFSPRITE: return ri->spriteref;
2965 case REFSPRITEDATA: return ri->spritedataref;
2966 case REFSTACK: return ri->stackref;
2967 49980 case REFSUBSCREENDATA: return ri->subscreendataref;
2968 2475 case REFSUBSCREENPAGE: return ri->subscreenpageref;
2969 102 case REFSUBSCREENWIDG: return ri->subscreenwidgref;
2970 case REFWEBSOCKET: return ri->websocketref;
2971
2972 default: NOTREACHED();
2973 }
2974 284185699 }
2975
2976 int32_t earlyretval = -1;
2977 4570302983 int32_t get_register(int32_t arg)
2978 {
2979
3/4
✓ Branch 0 taken 4570302983 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3270495049 times.
✓ Branch 3 taken 1299807934 times.
4570302983 if (arg >= D(0) && arg <= D(7))
2980 1299807934 return ri->d[arg - D(0)];
2981
2982
4/4
✓ Branch 0 taken 2675234685 times.
✓ Branch 1 taken 595260364 times.
✓ Branch 2 taken 2646579854 times.
✓ Branch 3 taken 28654831 times.
3270495049 if (arg >= GD(0) && arg <= GD(MAX_SCRIPT_REGISTERS))
2983 28654831 return game->global_d[arg - GD(0)];
2984
2985 3241840218 int32_t ret = 0;
2986
2987 #define GET_SPRITEDATA_VAR_INT(member) \
2988 { \
2989 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) ) \
2990 { \
2991 ret = -10000; \
2992 scripting_log_error_with_context("Invalid Sprite ID: {}", GET_REF(spritedataref)*10000); \
2993 } \
2994 else \
2995 ret = (wpnsbuf[GET_REF(spritedataref)].member * 10000); \
2996 }
2997
2998 3241840218 current_zasm_register = arg;
2999
3000 // Do not ever use `return` in these cases!
3001
288/1060
✗ Branch 0 not taken.
✓ Branch 1 taken 7214 times.
✓ Branch 2 taken 30000057 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1125668249 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 765028832 times.
✓ Branch 9 taken 3175268 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 623633 times.
✓ Branch 12 taken 13073815 times.
✓ Branch 13 taken 531425047 times.
✓ Branch 14 taken 2312686 times.
✓ Branch 15 taken 10 times.
✓ Branch 16 taken 24185371 times.
✓ Branch 17 taken 23746252 times.
✓ Branch 18 taken 5823966 times.
✓ Branch 19 taken 163102 times.
✓ Branch 20 taken 377 times.
✓ Branch 21 taken 51 times.
✓ Branch 22 taken 51 times.
✓ Branch 23 taken 204076 times.
✓ Branch 24 taken 199035 times.
✓ Branch 25 taken 5283857 times.
✓ Branch 26 taken 5194596 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 44546635 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 46258145 times.
✓ Branch 32 taken 4050508 times.
✓ Branch 33 taken 722055 times.
✓ Branch 34 taken 9096958 times.
✓ Branch 35 taken 441276 times.
✓ Branch 36 taken 27115881 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✓ Branch 39 taken 3407280 times.
✓ Branch 40 taken 1063999 times.
✓ Branch 41 taken 944878 times.
✓ Branch 42 taken 97952105 times.
✗ Branch 43 not taken.
✓ Branch 44 taken 204 times.
✓ Branch 45 taken 12148 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 1249005 times.
✓ Branch 48 taken 837632 times.
✓ Branch 49 taken 654959 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✓ Branch 53 taken 2161763 times.
✓ Branch 54 taken 1095514 times.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✓ Branch 58 taken 656387 times.
✓ Branch 59 taken 571655 times.
✓ Branch 60 taken 113145 times.
✓ Branch 61 taken 115547 times.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✓ Branch 66 taken 489104 times.
✓ Branch 67 taken 489104 times.
✓ Branch 68 taken 288295 times.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✓ Branch 71 taken 4101 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 57322 times.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✓ Branch 79 taken 180367 times.
✓ Branch 80 taken 440896 times.
✓ Branch 81 taken 2 times.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✓ Branch 84 taken 429515 times.
✓ Branch 85 taken 433515 times.
✓ Branch 86 taken 337540 times.
✓ Branch 87 taken 274017 times.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✓ Branch 90 taken 271788 times.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✓ Branch 95 taken 834841 times.
✓ Branch 96 taken 18 times.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✓ Branch 99 taken 4357 times.
✗ Branch 100 not taken.
✓ Branch 101 taken 13171261 times.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✓ Branch 119 taken 136185 times.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✓ Branch 128 taken 98023 times.
✓ Branch 129 taken 4123 times.
✓ Branch 130 taken 5056867 times.
✓ Branch 131 taken 4410418 times.
✓ Branch 132 taken 4977391 times.
✓ Branch 133 taken 5016239 times.
✓ Branch 134 taken 11970574 times.
✓ Branch 135 taken 10596134 times.
✓ Branch 136 taken 6428754 times.
✓ Branch 137 taken 6424495 times.
✓ Branch 138 taken 122646 times.
✓ Branch 139 taken 122937 times.
✓ Branch 140 taken 23391 times.
✓ Branch 141 taken 23391 times.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✗ Branch 145 not taken.
✓ Branch 146 taken 1054708 times.
✓ Branch 147 taken 1318385 times.
✗ Branch 148 not taken.
✓ Branch 149 taken 1073638 times.
✓ Branch 150 taken 1102950 times.
✓ Branch 151 taken 335996 times.
✓ Branch 152 taken 2151876 times.
✓ Branch 153 taken 1578611 times.
✓ Branch 154 taken 1805665 times.
✓ Branch 155 taken 1291881 times.
✓ Branch 156 taken 4122120 times.
✓ Branch 157 taken 3447036 times.
✓ Branch 158 taken 3697426 times.
✓ Branch 159 taken 3481646 times.
✓ Branch 160 taken 1779092 times.
✓ Branch 161 taken 1349984 times.
✓ Branch 162 taken 833679 times.
✓ Branch 163 taken 669416 times.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✓ Branch 194 taken 53 times.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 197 not taken.
✗ Branch 198 not taken.
✗ Branch 199 not taken.
✓ Branch 200 taken 58309993 times.
✓ Branch 201 taken 668845 times.
✓ Branch 202 taken 3 times.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✓ Branch 217 taken 1994 times.
✓ Branch 218 taken 1918 times.
✗ Branch 219 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✓ Branch 233 taken 55709 times.
✗ Branch 234 not taken.
✓ Branch 235 taken 55684 times.
✗ Branch 236 not taken.
✓ Branch 237 taken 63041 times.
✓ Branch 238 taken 142873 times.
✓ Branch 239 taken 74538 times.
✗ Branch 240 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 249 not taken.
✗ Branch 250 not taken.
✓ Branch 251 taken 954757 times.
✗ Branch 252 not taken.
✓ Branch 253 taken 950150 times.
✓ Branch 254 taken 109736 times.
✓ Branch 255 taken 6 times.
✗ Branch 256 not taken.
✓ Branch 257 taken 80933 times.
✗ Branch 258 not taken.
✓ Branch 259 taken 5388 times.
✓ Branch 260 taken 416 times.
✗ Branch 261 not taken.
✓ Branch 262 taken 246 times.
✗ Branch 263 not taken.
✓ Branch 264 taken 6 times.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✓ Branch 267 taken 6 times.
✓ Branch 268 taken 104531 times.
✓ Branch 269 taken 8339 times.
✓ Branch 270 taken 4517186 times.
✓ Branch 271 taken 53697 times.
✓ Branch 272 taken 586 times.
✗ Branch 273 not taken.
✓ Branch 274 taken 53381 times.
✓ Branch 275 taken 220 times.
✓ Branch 276 taken 4362 times.
✓ Branch 277 taken 6 times.
✓ Branch 278 taken 4622 times.
✓ Branch 279 taken 6 times.
✗ Branch 280 not taken.
✓ Branch 281 taken 2001860 times.
✓ Branch 282 taken 6 times.
✓ Branch 283 taken 835937 times.
✓ Branch 284 taken 23909 times.
✓ Branch 285 taken 299718 times.
✓ Branch 286 taken 296970 times.
✓ Branch 287 taken 10231 times.
✓ Branch 288 taken 11477 times.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 291 not taken.
✓ Branch 292 taken 6 times.
✓ Branch 293 taken 283042 times.
✓ Branch 294 taken 284996 times.
✓ Branch 295 taken 36540 times.
✓ Branch 296 taken 32019 times.
✓ Branch 297 taken 32019 times.
✓ Branch 298 taken 5469 times.
✗ Branch 299 not taken.
✓ Branch 300 taken 2166 times.
✗ Branch 301 not taken.
✓ Branch 302 taken 3 times.
✓ Branch 303 taken 60075 times.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✓ Branch 307 taken 1552 times.
✗ Branch 308 not taken.
✗ Branch 309 not taken.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✓ Branch 312 taken 48553 times.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 321 not taken.
✗ Branch 322 not taken.
✗ Branch 323 not taken.
✗ Branch 324 not taken.
✗ Branch 325 not taken.
✗ Branch 326 not taken.
✓ Branch 327 taken 4354592 times.
✗ Branch 328 not taken.
✓ Branch 329 taken 4354690 times.
✓ Branch 330 taken 552907 times.
✗ Branch 331 not taken.
✗ Branch 332 not taken.
✓ Branch 333 taken 61563 times.
✓ Branch 334 taken 2845 times.
✗ Branch 335 not taken.
✓ Branch 336 taken 647006 times.
✓ Branch 337 taken 908111 times.
✓ Branch 338 taken 3341 times.
✗ Branch 339 not taken.
✗ Branch 340 not taken.
✓ Branch 341 taken 170980 times.
✗ Branch 342 not taken.
✗ Branch 343 not taken.
✓ Branch 344 taken 46359 times.
✓ Branch 345 taken 99454 times.
✓ Branch 346 taken 6052 times.
✓ Branch 347 taken 2973313 times.
✓ Branch 348 taken 205116 times.
✗ Branch 349 not taken.
✗ Branch 350 not taken.
✓ Branch 351 taken 65418 times.
✗ Branch 352 not taken.
✓ Branch 353 taken 32642 times.
✗ Branch 354 not taken.
✓ Branch 355 taken 32642 times.
✗ Branch 356 not taken.
✓ Branch 357 taken 12006 times.
✓ Branch 358 taken 218 times.
✓ Branch 359 taken 6662442 times.
✗ Branch 360 not taken.
✓ Branch 361 taken 10635 times.
✗ Branch 362 not taken.
✓ Branch 363 taken 157773 times.
✓ Branch 364 taken 157773 times.
✓ Branch 365 taken 48464 times.
✓ Branch 366 taken 60558 times.
✗ Branch 367 not taken.
✗ Branch 368 not taken.
✗ Branch 369 not taken.
✓ Branch 370 taken 1880 times.
✓ Branch 371 taken 149564 times.
✓ Branch 372 taken 149564 times.
✓ Branch 373 taken 81355 times.
✓ Branch 374 taken 125257 times.
✓ Branch 375 taken 125257 times.
✓ Branch 376 taken 13583 times.
✗ Branch 377 not taken.
✗ Branch 378 not taken.
✗ Branch 379 not taken.
✗ Branch 380 not taken.
✓ Branch 381 taken 7568 times.
✗ Branch 382 not taken.
✗ Branch 383 not taken.
✗ Branch 384 not taken.
✗ Branch 385 not taken.
✗ Branch 386 not taken.
✓ Branch 387 taken 30735 times.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✗ Branch 390 not taken.
✗ Branch 391 not taken.
✗ Branch 392 not taken.
✗ Branch 393 not taken.
✗ Branch 394 not taken.
✗ Branch 395 not taken.
✗ Branch 396 not taken.
✗ Branch 397 not taken.
✗ Branch 398 not taken.
✗ Branch 399 not taken.
✗ Branch 400 not taken.
✗ Branch 401 not taken.
✓ Branch 402 taken 823233 times.
✗ Branch 403 not taken.
✗ Branch 404 not taken.
✗ Branch 405 not taken.
✓ Branch 406 taken 450 times.
✓ Branch 407 taken 107342 times.
✓ Branch 408 taken 12771766 times.
✓ Branch 409 taken 96 times.
✗ Branch 410 not taken.
✓ Branch 411 taken 65088848 times.
✓ Branch 412 taken 16014487 times.
✗ Branch 413 not taken.
✗ Branch 414 not taken.
✗ Branch 415 not taken.
✓ Branch 416 taken 390647 times.
✓ Branch 417 taken 382914 times.
✓ Branch 418 taken 2662 times.
✓ Branch 419 taken 2599 times.
✓ Branch 420 taken 11700413 times.
✓ Branch 421 taken 27276802 times.
✗ Branch 422 not taken.
✗ Branch 423 not taken.
✗ Branch 424 not taken.
✓ Branch 425 taken 24940 times.
✓ Branch 426 taken 21112 times.
✓ Branch 427 taken 8014 times.
✓ Branch 428 taken 11842 times.
✗ Branch 429 not taken.
✗ Branch 430 not taken.
✗ Branch 431 not taken.
✗ Branch 432 not taken.
✗ Branch 433 not taken.
✗ Branch 434 not taken.
✗ Branch 435 not taken.
✗ Branch 436 not taken.
✗ Branch 437 not taken.
✗ Branch 438 not taken.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✓ Branch 441 taken 170974 times.
✗ Branch 442 not taken.
✗ Branch 443 not taken.
✗ Branch 444 not taken.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✗ Branch 447 not taken.
✗ Branch 448 not taken.
✗ Branch 449 not taken.
✗ Branch 450 not taken.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✗ Branch 453 not taken.
✗ Branch 454 not taken.
✗ Branch 455 not taken.
✗ Branch 456 not taken.
✗ Branch 457 not taken.
✗ Branch 458 not taken.
✗ Branch 459 not taken.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 462 not taken.
✗ Branch 463 not taken.
✗ Branch 464 not taken.
✗ Branch 465 not taken.
✗ Branch 466 not taken.
✗ Branch 467 not taken.
✗ Branch 468 not taken.
✓ Branch 469 taken 17 times.
✗ Branch 470 not taken.
✗ Branch 471 not taken.
✗ Branch 472 not taken.
✗ Branch 473 not taken.
✗ Branch 474 not taken.
✓ Branch 475 taken 41995 times.
✗ Branch 476 not taken.
✗ Branch 477 not taken.
✓ Branch 478 taken 13968 times.
✓ Branch 479 taken 43250 times.
✗ Branch 480 not taken.
✓ Branch 481 taken 280 times.
✗ Branch 482 not taken.
✗ Branch 483 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 486 not taken.
✓ Branch 487 taken 10246 times.
✓ Branch 488 taken 2391 times.
✓ Branch 489 taken 47 times.
✓ Branch 490 taken 2 times.
✓ Branch 491 taken 748773 times.
✓ Branch 492 taken 112484 times.
✗ Branch 493 not taken.
✗ Branch 494 not taken.
✓ Branch 495 taken 1634 times.
✓ Branch 496 taken 1608 times.
✓ Branch 497 taken 32 times.
✗ Branch 498 not taken.
✗ Branch 499 not taken.
✗ Branch 500 not taken.
✓ Branch 501 taken 5603 times.
✗ Branch 502 not taken.
✓ Branch 503 taken 5603 times.
✗ Branch 504 not taken.
✓ Branch 505 taken 5603 times.
✓ Branch 506 taken 5603 times.
✗ Branch 507 not taken.
✗ Branch 508 not taken.
✓ Branch 509 taken 7237302 times.
✓ Branch 510 taken 1509495 times.
✓ Branch 511 taken 51072 times.
✗ Branch 512 not taken.
✗ Branch 513 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 516 not taken.
✗ Branch 517 not taken.
✗ Branch 518 not taken.
✗ Branch 519 not taken.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✗ Branch 522 not taken.
✗ Branch 523 not taken.
✓ Branch 524 taken 51072 times.
✗ Branch 525 not taken.
✗ Branch 526 not taken.
✗ Branch 527 not taken.
✗ Branch 528 not taken.
✗ Branch 529 not taken.
✗ Branch 530 not taken.
✗ Branch 531 not taken.
✗ Branch 532 not taken.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✗ Branch 538 not taken.
✗ Branch 539 not taken.
✗ Branch 540 not taken.
✗ Branch 541 not taken.
✗ Branch 542 not taken.
✗ Branch 543 not taken.
✗ Branch 544 not taken.
✗ Branch 545 not taken.
✗ Branch 546 not taken.
✓ Branch 547 taken 32 times.
✓ Branch 548 taken 2004 times.
✗ Branch 549 not taken.
✗ Branch 550 not taken.
✗ Branch 551 not taken.
✗ Branch 552 not taken.
✗ Branch 553 not taken.
✗ Branch 554 not taken.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 558 not taken.
✗ Branch 559 not taken.
✓ Branch 560 taken 151527 times.
✓ Branch 561 taken 314379 times.
✗ Branch 562 not taken.
✗ Branch 563 not taken.
✗ Branch 564 not taken.
✗ Branch 565 not taken.
✓ Branch 566 taken 1402 times.
✓ Branch 567 taken 193590 times.
✗ Branch 568 not taken.
✗ Branch 569 not taken.
✓ Branch 570 taken 8824 times.
✓ Branch 571 taken 128960 times.
✓ Branch 572 taken 51092 times.
✓ Branch 573 taken 814 times.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 576 not taken.
✗ Branch 577 not taken.
✓ Branch 578 taken 13125 times.
✓ Branch 579 taken 1192906 times.
✗ Branch 580 not taken.
✗ Branch 581 not taken.
✓ Branch 582 taken 5120 times.
✗ Branch 583 not taken.
✗ Branch 584 not taken.
✗ Branch 585 not taken.
✗ Branch 586 not taken.
✗ Branch 587 not taken.
✗ Branch 588 not taken.
✗ Branch 589 not taken.
✗ Branch 590 not taken.
✗ Branch 591 not taken.
✓ Branch 592 taken 23552 times.
✗ Branch 593 not taken.
✗ Branch 594 not taken.
✗ Branch 595 not taken.
✗ Branch 596 not taken.
✗ Branch 597 not taken.
✗ Branch 598 not taken.
✗ Branch 599 not taken.
✗ Branch 600 not taken.
✗ Branch 601 not taken.
✗ Branch 602 not taken.
✗ Branch 603 not taken.
✗ Branch 604 not taken.
✗ Branch 605 not taken.
✗ Branch 606 not taken.
✗ Branch 607 not taken.
✗ Branch 608 not taken.
✗ Branch 609 not taken.
✗ Branch 610 not taken.
✗ Branch 611 not taken.
✗ Branch 612 not taken.
✗ Branch 613 not taken.
✗ Branch 614 not taken.
✗ Branch 615 not taken.
✗ Branch 616 not taken.
✗ Branch 617 not taken.
✓ Branch 618 taken 182307 times.
✓ Branch 619 taken 134178 times.
✓ Branch 620 taken 629336 times.
✓ Branch 621 taken 19185 times.
✓ Branch 622 taken 116988 times.
✓ Branch 623 taken 122133 times.
✓ Branch 624 taken 9711 times.
✗ Branch 625 not taken.
✓ Branch 626 taken 2 times.
✓ Branch 627 taken 14257 times.
✓ Branch 628 taken 6890 times.
✓ Branch 629 taken 755 times.
✓ Branch 630 taken 12398 times.
✗ Branch 631 not taken.
✗ Branch 632 not taken.
✗ Branch 633 not taken.
✓ Branch 634 taken 528885 times.
✓ Branch 635 taken 2 times.
✗ Branch 636 not taken.
✗ Branch 637 not taken.
✗ Branch 638 not taken.
✗ Branch 639 not taken.
✗ Branch 640 not taken.
✗ Branch 641 not taken.
✓ Branch 642 taken 5429248 times.
✓ Branch 643 taken 18 times.
✗ Branch 644 not taken.
✗ Branch 645 not taken.
✗ Branch 646 not taken.
✗ Branch 647 not taken.
✗ Branch 648 not taken.
✗ Branch 649 not taken.
✗ Branch 650 not taken.
✗ Branch 651 not taken.
✗ Branch 652 not taken.
✗ Branch 653 not taken.
✗ Branch 654 not taken.
✗ Branch 655 not taken.
✗ Branch 656 not taken.
✗ Branch 657 not taken.
✗ Branch 658 not taken.
✓ Branch 659 taken 25 times.
✗ Branch 660 not taken.
✗ Branch 661 not taken.
✗ Branch 662 not taken.
✗ Branch 663 not taken.
✗ Branch 664 not taken.
✗ Branch 665 not taken.
✗ Branch 666 not taken.
✗ Branch 667 not taken.
✗ Branch 668 not taken.
✗ Branch 669 not taken.
✗ Branch 670 not taken.
✗ Branch 671 not taken.
✗ Branch 672 not taken.
✗ Branch 673 not taken.
✗ Branch 674 not taken.
✗ Branch 675 not taken.
✗ Branch 676 not taken.
✗ Branch 677 not taken.
✗ Branch 678 not taken.
✗ Branch 679 not taken.
✗ Branch 680 not taken.
✗ Branch 681 not taken.
✗ Branch 682 not taken.
✗ Branch 683 not taken.
✗ Branch 684 not taken.
✗ Branch 685 not taken.
✗ Branch 686 not taken.
✗ Branch 687 not taken.
✗ Branch 688 not taken.
✗ Branch 689 not taken.
✗ Branch 690 not taken.
✗ Branch 691 not taken.
✗ Branch 692 not taken.
✗ Branch 693 not taken.
✗ Branch 694 not taken.
✗ Branch 695 not taken.
✗ Branch 696 not taken.
✗ Branch 697 not taken.
✗ Branch 698 not taken.
✗ Branch 699 not taken.
✓ Branch 700 taken 5246834 times.
✗ Branch 701 not taken.
✗ Branch 702 not taken.
✗ Branch 703 not taken.
✗ Branch 704 not taken.
✗ Branch 705 not taken.
✗ Branch 706 not taken.
✗ Branch 707 not taken.
✗ Branch 708 not taken.
✗ Branch 709 not taken.
✗ Branch 710 not taken.
✗ Branch 711 not taken.
✗ Branch 712 not taken.
✗ Branch 713 not taken.
✗ Branch 714 not taken.
✗ Branch 715 not taken.
✗ Branch 716 not taken.
✗ Branch 717 not taken.
✗ Branch 718 not taken.
✗ Branch 719 not taken.
✗ Branch 720 not taken.
✗ Branch 721 not taken.
✗ Branch 722 not taken.
✗ Branch 723 not taken.
✗ Branch 724 not taken.
✗ Branch 725 not taken.
✗ Branch 726 not taken.
✗ Branch 727 not taken.
✗ Branch 728 not taken.
✗ Branch 729 not taken.
✗ Branch 730 not taken.
✗ Branch 731 not taken.
✗ Branch 732 not taken.
✗ Branch 733 not taken.
✗ Branch 734 not taken.
✗ Branch 735 not taken.
✗ Branch 736 not taken.
✗ Branch 737 not taken.
✗ Branch 738 not taken.
✗ Branch 739 not taken.
✗ Branch 740 not taken.
✗ Branch 741 not taken.
✗ Branch 742 not taken.
✗ Branch 743 not taken.
✗ Branch 744 not taken.
✗ Branch 745 not taken.
✗ Branch 746 not taken.
✗ Branch 747 not taken.
✗ Branch 748 not taken.
✗ Branch 749 not taken.
✗ Branch 750 not taken.
✗ Branch 751 not taken.
✗ Branch 752 not taken.
✗ Branch 753 not taken.
✗ Branch 754 not taken.
✗ Branch 755 not taken.
✗ Branch 756 not taken.
✗ Branch 757 not taken.
✗ Branch 758 not taken.
✗ Branch 759 not taken.
✗ Branch 760 not taken.
✗ Branch 761 not taken.
✗ Branch 762 not taken.
✗ Branch 763 not taken.
✗ Branch 764 not taken.
✗ Branch 765 not taken.
✗ Branch 766 not taken.
✗ Branch 767 not taken.
✗ Branch 768 not taken.
✗ Branch 769 not taken.
✗ Branch 770 not taken.
✗ Branch 771 not taken.
✗ Branch 772 not taken.
✗ Branch 773 not taken.
✗ Branch 774 not taken.
✗ Branch 775 not taken.
✗ Branch 776 not taken.
✗ Branch 777 not taken.
✗ Branch 778 not taken.
✗ Branch 779 not taken.
✗ Branch 780 not taken.
✗ Branch 781 not taken.
✗ Branch 782 not taken.
✗ Branch 783 not taken.
✗ Branch 784 not taken.
✗ Branch 785 not taken.
✗ Branch 786 not taken.
✗ Branch 787 not taken.
✗ Branch 788 not taken.
✗ Branch 789 not taken.
✗ Branch 790 not taken.
✗ Branch 791 not taken.
✗ Branch 792 not taken.
✗ Branch 793 not taken.
✗ Branch 794 not taken.
✗ Branch 795 not taken.
✗ Branch 796 not taken.
✗ Branch 797 not taken.
✗ Branch 798 not taken.
✗ Branch 799 not taken.
✗ Branch 800 not taken.
✗ Branch 801 not taken.
✗ Branch 802 not taken.
✗ Branch 803 not taken.
✗ Branch 804 not taken.
✗ Branch 805 not taken.
✗ Branch 806 not taken.
✗ Branch 807 not taken.
✗ Branch 808 not taken.
✗ Branch 809 not taken.
✗ Branch 810 not taken.
✗ Branch 811 not taken.
✗ Branch 812 not taken.
✗ Branch 813 not taken.
✗ Branch 814 not taken.
✗ Branch 815 not taken.
✗ Branch 816 not taken.
✗ Branch 817 not taken.
✗ Branch 818 not taken.
✗ Branch 819 not taken.
✗ Branch 820 not taken.
✗ Branch 821 not taken.
✗ Branch 822 not taken.
✗ Branch 823 not taken.
✗ Branch 824 not taken.
✗ Branch 825 not taken.
✗ Branch 826 not taken.
✗ Branch 827 not taken.
✗ Branch 828 not taken.
✗ Branch 829 not taken.
✗ Branch 830 not taken.
✗ Branch 831 not taken.
✗ Branch 832 not taken.
✗ Branch 833 not taken.
✗ Branch 834 not taken.
✗ Branch 835 not taken.
✗ Branch 836 not taken.
✓ Branch 837 taken 3182 times.
✗ Branch 838 not taken.
✗ Branch 839 not taken.
✗ Branch 840 not taken.
✗ Branch 841 not taken.
✓ Branch 842 taken 3182 times.
✗ Branch 843 not taken.
✗ Branch 844 not taken.
✗ Branch 845 not taken.
✗ Branch 846 not taken.
✗ Branch 847 not taken.
✗ Branch 848 not taken.
✗ Branch 849 not taken.
✗ Branch 850 not taken.
✗ Branch 851 not taken.
✗ Branch 852 not taken.
✗ Branch 853 not taken.
✗ Branch 854 not taken.
✗ Branch 855 not taken.
✗ Branch 856 not taken.
✓ Branch 857 taken 1 times.
✓ Branch 858 taken 1 times.
✗ Branch 859 not taken.
✗ Branch 860 not taken.
✗ Branch 861 not taken.
✗ Branch 862 not taken.
✗ Branch 863 not taken.
✗ Branch 864 not taken.
✗ Branch 865 not taken.
✗ Branch 866 not taken.
✗ Branch 867 not taken.
✗ Branch 868 not taken.
✗ Branch 869 not taken.
✗ Branch 870 not taken.
✗ Branch 871 not taken.
✗ Branch 872 not taken.
✗ Branch 873 not taken.
✗ Branch 874 not taken.
✗ Branch 875 not taken.
✗ Branch 876 not taken.
✗ Branch 877 not taken.
✗ Branch 878 not taken.
✗ Branch 879 not taken.
✗ Branch 880 not taken.
✓ Branch 881 taken 10 times.
✗ Branch 882 not taken.
✗ Branch 883 not taken.
✗ Branch 884 not taken.
✓ Branch 885 taken 3453 times.
✗ Branch 886 not taken.
✗ Branch 887 not taken.
✗ Branch 888 not taken.
✓ Branch 889 taken 28445 times.
✓ Branch 890 taken 608662 times.
✓ Branch 891 taken 57964044 times.
✓ Branch 892 taken 2054459 times.
✓ Branch 893 taken 5970308 times.
✓ Branch 894 taken 32182956 times.
✗ Branch 895 not taken.
✗ Branch 896 not taken.
✓ Branch 897 taken 20 times.
✓ Branch 898 taken 5774191 times.
✗ Branch 899 not taken.
✓ Branch 900 taken 5603 times.
✓ Branch 901 taken 10 times.
✓ Branch 902 taken 2 times.
✓ Branch 903 taken 549327 times.
✗ Branch 904 not taken.
✓ Branch 905 taken 54 times.
✓ Branch 906 taken 10 times.
✗ Branch 907 not taken.
✗ Branch 908 not taken.
✓ Branch 909 taken 137856 times.
✗ Branch 910 not taken.
✗ Branch 911 not taken.
✗ Branch 912 not taken.
✓ Branch 913 taken 91 times.
✗ Branch 914 not taken.
✗ Branch 915 not taken.
✗ Branch 916 not taken.
✓ Branch 917 taken 733584 times.
✓ Branch 918 taken 1134 times.
✗ Branch 919 not taken.
✗ Branch 920 not taken.
✓ Branch 921 taken 279874 times.
✗ Branch 922 not taken.
✗ Branch 923 not taken.
✗ Branch 924 not taken.
✓ Branch 925 taken 7697 times.
✗ Branch 926 not taken.
✗ Branch 927 not taken.
✗ Branch 928 not taken.
✗ Branch 929 not taken.
✗ Branch 930 not taken.
✗ Branch 931 not taken.
✗ Branch 932 not taken.
✗ Branch 933 not taken.
✗ Branch 934 not taken.
✗ Branch 935 not taken.
✗ Branch 936 not taken.
✗ Branch 937 not taken.
✗ Branch 938 not taken.
✗ Branch 939 not taken.
✗ Branch 940 not taken.
✗ Branch 941 not taken.
✗ Branch 942 not taken.
✗ Branch 943 not taken.
✗ Branch 944 not taken.
✗ Branch 945 not taken.
✗ Branch 946 not taken.
✗ Branch 947 not taken.
✗ Branch 948 not taken.
✗ Branch 949 not taken.
✗ Branch 950 not taken.
✗ Branch 951 not taken.
✗ Branch 952 not taken.
✗ Branch 953 not taken.
✗ Branch 954 not taken.
✓ Branch 955 taken 47730 times.
✗ Branch 956 not taken.
✗ Branch 957 not taken.
✗ Branch 958 not taken.
✗ Branch 959 not taken.
✓ Branch 960 taken 54674 times.
✓ Branch 961 taken 11 times.
✗ Branch 962 not taken.
✗ Branch 963 not taken.
✗ Branch 964 not taken.
✗ Branch 965 not taken.
✗ Branch 966 not taken.
✗ Branch 967 not taken.
✗ Branch 968 not taken.
✗ Branch 969 not taken.
✗ Branch 970 not taken.
✗ Branch 971 not taken.
✗ Branch 972 not taken.
✓ Branch 973 taken 5031 times.
✗ Branch 974 not taken.
✗ Branch 975 not taken.
✗ Branch 976 not taken.
✗ Branch 977 not taken.
✓ Branch 978 taken 1005 times.
✗ Branch 979 not taken.
✓ Branch 980 taken 17326 times.
✓ Branch 981 taken 6024 times.
✗ Branch 982 not taken.
✓ Branch 983 taken 4206 times.
✓ Branch 984 taken 9836 times.
✗ Branch 985 not taken.
✗ Branch 986 not taken.
✓ Branch 987 taken 339 times.
✓ Branch 988 taken 339 times.
✗ Branch 989 not taken.
✗ Branch 990 not taken.
✗ Branch 991 not taken.
✗ Branch 992 not taken.
✗ Branch 993 not taken.
✗ Branch 994 not taken.
✗ Branch 995 not taken.
✗ Branch 996 not taken.
✗ Branch 997 not taken.
✗ Branch 998 not taken.
✗ Branch 999 not taken.
✗ Branch 1000 not taken.
✗ Branch 1001 not taken.
✗ Branch 1002 not taken.
✗ Branch 1003 not taken.
✗ Branch 1004 not taken.
✗ Branch 1005 not taken.
✗ Branch 1006 not taken.
✗ Branch 1007 not taken.
✗ Branch 1008 not taken.
✗ Branch 1009 not taken.
✗ Branch 1010 not taken.
✗ Branch 1011 not taken.
✗ Branch 1012 not taken.
✗ Branch 1013 not taken.
✗ Branch 1014 not taken.
✗ Branch 1015 not taken.
✗ Branch 1016 not taken.
✗ Branch 1017 not taken.
✗ Branch 1018 not taken.
✗ Branch 1019 not taken.
✗ Branch 1020 not taken.
✗ Branch 1021 not taken.
✗ Branch 1022 not taken.
✗ Branch 1023 not taken.
✗ Branch 1024 not taken.
✗ Branch 1025 not taken.
✗ Branch 1026 not taken.
✗ Branch 1027 not taken.
✗ Branch 1028 not taken.
✗ Branch 1029 not taken.
✗ Branch 1030 not taken.
✗ Branch 1031 not taken.
✗ Branch 1032 not taken.
✗ Branch 1033 not taken.
✗ Branch 1034 not taken.
✓ Branch 1035 taken 1455 times.
✗ Branch 1036 not taken.
✗ Branch 1037 not taken.
✗ Branch 1038 not taken.
✗ Branch 1039 not taken.
✗ Branch 1040 not taken.
✗ Branch 1041 not taken.
✗ Branch 1042 not taken.
✗ Branch 1043 not taken.
✗ Branch 1044 not taken.
✗ Branch 1045 not taken.
✗ Branch 1046 not taken.
✗ Branch 1047 not taken.
✗ Branch 1048 not taken.
✗ Branch 1049 not taken.
✗ Branch 1050 not taken.
✗ Branch 1051 not taken.
✗ Branch 1052 not taken.
✗ Branch 1053 not taken.
✗ Branch 1054 not taken.
✗ Branch 1055 not taken.
✗ Branch 1056 not taken.
✗ Branch 1057 not taken.
✗ Branch 1058 not taken.
✗ Branch 1059 not taken.
3241840218 switch(arg)
3002 {
3003 case MAX_FFC_ID:
3004 {
3005 3175268 ret = (MAX_FFCID + 1) * 10000;
3006 3175268 break;
3007 }
3008
3009 case INCQST:
3010 {
3011 int32_t newqst = 0;
3012 if ( game->get_quest() < 255 ) //255 is a custom quest
3013 {
3014 newqst = (game->get_quest()+1);
3015 }
3016 else
3017 {
3018 newqst = 1;
3019 }
3020 if ( newqst < 11 )
3021 {
3022
3023 ret = newqst * 10000;
3024 Quit = qINCQST;
3025 //ending();
3026
3027 }
3028 else ret = -10000;
3029 break;
3030 }
3031 case DEBUGTESTING:
3032 623633 ret = use_testingst_start ? 10000 : 0;
3033 623633 break;
3034
3035 ///----------------------------------------------------------------------------------------------------//
3036 //FFC Variables
3037 case DATA:
3038
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13073813 times.
13073815 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
3039 13073813 ret = ffc->data * 10000;
3040 13073815 break;
3041
3042 case FFSCRIPT:
3043
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 531424835 times.
531425047 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3044 531424835 ret = ffc->script * 10000;
3045 531425047 break;
3046
3047 case FCSET:
3048
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2312686 times.
2312686 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3049 2312686 ret = ffc->cset * 10000;
3050 2312686 break;
3051
3052 case DELAY:
3053
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3054 10 ret = ffc->delay * 10000;
3055 10 break;
3056
3057 case FX:
3058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24185371 times.
24185371 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3059 24185371 ret = ffc->x.getZLong();
3060 24185371 break;
3061
3062 case FY:
3063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23746252 times.
23746252 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3064 23746252 ret = ffc->y.getZLong();
3065 23746252 break;
3066
3067 case XD:
3068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5823966 times.
5823966 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3069 5823966 ret = ffc->vx.getZLong();
3070 5823966 break;
3071
3072 case YD:
3073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 163102 times.
163102 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3074 163102 ret = ffc->vy.getZLong();
3075 163102 break;
3076 case FFCID:
3077
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377 times.
377 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
3078 377 ret = (get_region_screen_offset(ffc->screen_spawned) * MAXFFCS + ffc->index + 1) * 10000;
3079 377 break;
3080
3081 case XD2:
3082
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3083 51 ret = ffc->ax.getZLong();
3084 51 break;
3085
3086 case YD2:
3087
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3088 51 ret = ffc->ay.getZLong();
3089 51 break;
3090
3091 case FFCWIDTH:
3092
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 204076 times.
204076 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3093 204076 ret = ffc->hit_width * 10000;
3094 204076 break;
3095
3096 case FFCHEIGHT:
3097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199035 times.
199035 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3098 199035 ret = ffc->hit_height * 10000;
3099 199035 break;
3100
3101 case FFTWIDTH:
3102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5283857 times.
5283857 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3103 5283857 ret = ffc->txsz * 10000;
3104 5283857 break;
3105
3106 case FFTHEIGHT:
3107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5194596 times.
5194596 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3108 5194596 ret = ffc->tysz * 10000;
3109 5194596 break;
3110
3111 case FFCLAYER:
3112 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
3113 ret = ffc->layer * 10000;
3114 break;
3115
3116 case FFLINK:
3117 if(auto ffc = ResolveFFC(GET_REF(ffcref)))
3118 ret = ffc->link * 10000;
3119 break;
3120
3121 ///----------------------------------------------------------------------------------------------------//
3122 //Hero's Variables
3123 case LINKX:
3124 {
3125
2/2
✓ Branch 0 taken 8978773 times.
✓ Branch 1 taken 35567862 times.
44546635 if (get_qr(qr_SPRITEXY_IS_FLOAT))
3126 {
3127 8978773 ret = Hero.getX().getZLong();
3128 8978773 }
3129 35567862 else ret = int32_t(Hero.getX()) * 10000;
3130
3131 44546635 break;
3132 }
3133
3134 case LINKCSET:
3135 {
3136 ret = Hero.cs * 10000;
3137 break;
3138 }
3139 case LINKY:
3140 {
3141
2/2
✓ Branch 0 taken 9795302 times.
✓ Branch 1 taken 36462843 times.
46258145 if (get_qr(qr_SPRITEXY_IS_FLOAT))
3142 {
3143 9795302 ret = Hero.getY().getZLong();
3144 9795302 }
3145 36462843 else ret = int32_t(Hero.getY()) * 10000;
3146
3147 46258145 break;
3148 }
3149 case LINKZ:
3150 {
3151
2/2
✓ Branch 0 taken 2849746 times.
✓ Branch 1 taken 1200762 times.
4050508 if (get_qr(qr_SPRITEXY_IS_FLOAT))
3152 {
3153 2849746 ret = Hero.getZ().getZLong();
3154 2849746 }
3155 1200762 else ret = int32_t(Hero.getZ()) * 10000;
3156
3157 4050508 break;
3158 }
3159 case LINKJUMP:
3160 722055 ret = Hero.getJump().getZLong();
3161 722055 break;
3162
3163 case HEROFAKEJUMP:
3164 ret = Hero.getFakeJump().getZLong() / -100;
3165 break;
3166
3167 case LINKDIR:
3168 9096958 ret=(int32_t)(Hero.dir)*10000;
3169 9096958 break;
3170
3171 case LINKHITDIR:
3172 441276 ret=(int32_t)(Hero.getHitDir())*10000;
3173 441276 break;
3174
3175 case LINKHP:
3176 27115881 ret=(int32_t)(game->get_life())*10000;
3177 27115881 break;
3178
3179 case LINKGRAVITY:
3180 ret = ( (Hero.moveflags & move_obeys_grav) ? 10000 : 0 );
3181 break;
3182
3183 case HERONOSTEPFORWARD:
3184 ret = ( (FFCore.nostepforward) ? 10000 : 0 );
3185 break;
3186
3187 case LINKMP:
3188 3407280 ret=(int32_t)(game->get_magic())*10000;
3189 3407280 break;
3190
3191 case LINKMAXHP:
3192 1063999 ret=(int32_t)(game->get_maxlife())*10000;
3193 1063999 break;
3194
3195 case LINKMAXMP:
3196 944878 ret=(int32_t)(game->get_maxmagic())*10000;
3197 944878 break;
3198
3199 case LINKACTION:
3200 {
3201 97952105 ret = FFCore.getHeroAction() * 10000;
3202 97952105 break;
3203 }
3204
3205 case HEROHEALTHBEEP:
3206 {
3207 ret = heart_beep ? ( heart_beep_timer * 10000 ) : 0;
3208 break;
3209 }
3210
3211 case LINKHELD:
3212 204 ret = (int32_t)(Hero.getHeldItem())*10000;
3213 204 break;
3214
3215 case HEROSTEPRATE:
3216 12148 ret = Hero.getStepRate() * 10000;
3217 12148 break;
3218 case HEROSHOVEOFFSET:
3219 ret = Hero.shove_offset.getZLong();
3220 break;
3221
3222 case LINKEQUIP:
3223 1249005 ret = ((Awpn&0xFF)|((Bwpn&0xFF)<<8))*10000;
3224 1249005 break;
3225
3226 case LINKINVIS:
3227 837632 ret = (((int32_t)(Hero.getDontDraw())) ? 10000 : 0);
3228 837632 break;
3229
3230 case LINKINVINC:
3231 654959 ret = (int32_t)(Hero.scriptcoldet)*10000;
3232 654959 break;
3233
3234 case LINKENGINEANIMATE:
3235 ret = (int32_t)(Hero.do_animation)*10000;
3236 break;
3237
3238 case LINKLADDERX:
3239 ret=(int32_t)(Hero.getLadderX())*10000;
3240 break;
3241
3242 case LINKLADDERY:
3243 ret=(int32_t)(Hero.getLadderY())*10000;
3244 break;
3245
3246 case LINKSWORDJINX:
3247 2161763 ret = (int32_t)(Hero.getSwordClk())*10000;
3248 2161763 break;
3249
3250 case LINKITEMJINX:
3251 1095514 ret = (int32_t)(Hero.getItemClk())*10000;
3252 1095514 break;
3253
3254 case LINKDRUNK:
3255 ret = (int32_t)(Hero.DrunkClock())*10000;
3256 break;
3257
3258 case LINKROTATION:
3259 if ( get_qr(qr_OLDSPRITEDRAWS) )
3260 {
3261 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
3262 ret = -1; break;
3263 }
3264 ret = (int32_t)(Hero.rotation)*10000;
3265 break;
3266
3267 case LINKSCALE:
3268 {
3269 if ( get_qr(qr_OLDSPRITEDRAWS) )
3270 {
3271 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
3272 ret = -1; break;
3273 }
3274 ret = (int32_t)(Hero.scale*100.0);
3275 break;
3276 }
3277
3278
3279 case LINKHXOFS:
3280 656387 ret = (int32_t)(Hero.hxofs)*10000;
3281 656387 break;
3282
3283 case LINKHYOFS:
3284 571655 ret = (int32_t)(Hero.hyofs)*10000;
3285 571655 break;
3286
3287 case LINKXOFS:
3288 113145 ret = (int32_t)(Hero.xofs)*10000;
3289 113145 break;
3290
3291 case LINKYOFS:
3292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115547 times.
115547 ret = (int32_t)(Hero.yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset))*10000;
3293 115547 break;
3294
3295 case HEROSHADOWXOFS:
3296 ret = (int32_t)(Hero.shadowxofs)*10000;
3297 break;
3298
3299 case HEROSHADOWYOFS:
3300 ret = (int32_t)(Hero.shadowyofs)*10000;
3301 break;
3302
3303 case HEROTOTALDYOFFS:
3304 ret = 10000*(((int32_t)(Hero.yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)))
3305 + ((Hero.switch_hooked && Hero.switchhookstyle == swRISE)
3306 ? -(8-(abs(Hero.switchhookclk-32)/4)) : 0));
3307 break;
3308
3309 case LINKZOFS:
3310 ret = (int32_t)(Hero.zofs)*10000;
3311 break;
3312
3313 case LINKHXSZ:
3314 489104 ret = (int32_t)(Hero.hit_width)*10000;
3315 489104 break;
3316
3317 case LINKHYSZ:
3318 489104 ret = (int32_t)(Hero.hit_height)*10000;
3319 489104 break;
3320
3321 case LINKHZSZ:
3322 288295 ret = (int32_t)(Hero.hzsz)*10000;
3323 288295 break;
3324
3325 case LINKTXSZ:
3326 ret = (int32_t)(Hero.txsz)*10000;
3327 break;
3328
3329 case LINKTYSZ:
3330 ret = (int32_t)(Hero.tysz)*10000;
3331 break;
3332
3333 case LINKTILE:
3334 4101 ret = (int32_t)(Hero.tile)*10000;
3335 4101 break;
3336
3337 case LINKFLIP:
3338 ret = (int32_t)(Hero.flip)*10000;
3339 break;
3340
3341 case LINKINVFRAME:
3342 57322 ret = (int32_t)Hero.getHClk()*10000;
3343 57322 break;
3344
3345 case LINKCANFLICKER:
3346 ret= Hero.getCanFlicker()?10000:0;
3347 break;
3348 case LINKHURTSFX:
3349 ret = (int32_t)Hero.getHurtSFX()*10000;
3350 break;
3351
3352 /*
3353 case LINKUSINGITEM:
3354 ret = (int32_t)Hero.getDirectItem()*10000;
3355 break;
3356
3357 case LINKUSINGITEMA:
3358 ret = (int32_t)Hero.getDirectItemA()*10000;
3359 break;
3360
3361 case LINKUSINGITEMB:
3362 ret = (int32_t)Hero.getDirectItemB()*10000;
3363 break;
3364 */
3365
3366 case LINKEATEN:
3367 ret=(int32_t)Hero.getEaten()*10000;
3368 break;
3369 case LINKGRABBED:
3370 ret = Hero.inwallm ? 10000 : 0;
3371 break;
3372 case HEROBUNNY:
3373 ret = Hero.BunnyClock()*10000;
3374 break;
3375 case LINKPUSH:
3376 180367 ret=(int32_t)Hero.getPushing()*10000;
3377 180367 break;
3378 case LINKSTUN:
3379 440896 ret=(int32_t)Hero.StunClock()*10000;
3380 440896 break;
3381 case LINKSCRIPTTILE:
3382 2 ret=script_hero_sprite*10000;
3383 2 break;
3384
3385 case HEROSCRIPTCSET:
3386 ret=script_hero_cset*10000;
3387 break;
3388 case LINKSCRIPFLIP:
3389 ret=script_hero_flip*10000;
3390 break;
3391
3392
3393 case LINKITEMB:
3394 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
3395 429515 ret = Bwpn*10000;
3396 429515 break;
3397
3398 case LINKITEMA:
3399 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
3400 433515 ret = Awpn *10000;
3401 433515 break;
3402
3403 case LINKITEMX:
3404 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
3405 337540 ret = Xwpn *10000;
3406 337540 break;
3407
3408 case LINKITEMY:
3409 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
3410 274017 ret = Ywpn *10000;
3411 274017 break;
3412
3413 case LINKTILEMOD:
3414 ret = Hero.getTileModifier() * 10000;
3415 break;
3416
3417 case LINKDIAG:
3418 ret=Hero.getDiagMove()?10000:0;
3419 break;
3420
3421 case LINKBIGHITBOX:
3422 271788 ret=Hero.getBigHitbox()?10000:0;
3423 271788 break;
3424
3425 case LINKCLIMBING:
3426 ret = Hero.getOnSideviewLadder()?10000:0;
3427 break;
3428
3429 case HEROJUMPCOUNT:
3430 ret = Hero.extra_jump_count * 10000;
3431 break;
3432
3433 case HEROPULLDIR:
3434 ret = Hero.pit_pulldir * 10000;
3435 break;
3436
3437 case HEROPULLCLK:
3438 ret = Hero.pit_pullclk * 10000;
3439 break;
3440
3441 case HEROFALLCLK:
3442 834841 ret = Hero.fallclk * 10000;
3443 834841 break;
3444
3445 case HEROFALLCMB:
3446 18 ret = Hero.fallCombo * 10000;
3447 18 break;
3448
3449 case HERODROWNCLK:
3450 ret = Hero.drownclk * 10000;
3451 break;
3452
3453 case HERODROWNCMB:
3454 ret = Hero.drownCombo * 10000;
3455 break;
3456
3457 case HEROFAKEZ:
3458 {
3459
1/2
✓ Branch 0 taken 4357 times.
✗ Branch 1 not taken.
4357 if (get_qr(qr_SPRITEXY_IS_FLOAT))
3460 {
3461 4357 ret = Hero.getFakeZ().getZLong();
3462 4357 }
3463 else ret = int32_t(Hero.getFakeZ()) * 10000;
3464
3465 4357 break;
3466 }
3467
3468 case HEROSHIELDJINX:
3469 ret = Hero.shieldjinxclk * 10000;
3470 break;
3471
3472 case HEROISWARPING:
3473 13171261 ret = Hero.is_warping ? 10000L : 0L;
3474 13171261 break;
3475
3476 case CLOCKACTIVE:
3477 ret=watch?10000:0;
3478 break;
3479
3480 case CLOCKCLK:
3481 ret=clockclk*10000;
3482 break;
3483
3484 case HERORESPAWNX:
3485 {
3486 ret = Hero.respawn_x.getZLong();
3487 break;
3488 }
3489
3490 case HERORESPAWNY:
3491 {
3492 ret = Hero.respawn_y.getZLong();
3493 break;
3494 }
3495
3496 case HERORESPAWNDMAP:
3497 {
3498 ret = Hero.respawn_dmap * 10000;
3499 break;
3500 }
3501
3502 case HERORESPAWNSCR:
3503 {
3504 ret = Hero.respawn_scr * 10000;
3505 break;
3506 }
3507
3508 case HEROSWITCHTIMER:
3509 {
3510 ret = Hero.switchhookclk * 10000;
3511 break;
3512 }
3513
3514 case HEROSWITCHMAXTIMER:
3515 {
3516 ret = Hero.switchhookmaxtime * 10000;
3517 break;
3518 }
3519
3520 case HEROIMMORTAL:
3521 {
3522 ret = Hero.immortal * 10000;
3523 break;
3524 }
3525
3526 case HEROSTANDING:
3527 {
3528 ret = Hero.isStanding(true) ? 10000 : 0;
3529 break;
3530 }
3531
3532 case HEROCOYOTETIME:
3533 {
3534 ret = Hero.coyotetime*10000;
3535 break;
3536 }
3537
3538 case HEROLIFTEDWPN:
3539 {
3540 ret = Hero.lift_wpn ? Hero.lift_wpn->getUID() : 0;
3541 break;
3542 }
3543 case HEROLIFTTIMER:
3544 {
3545 ret = Hero.liftclk * 10000;
3546 break;
3547 }
3548 case HEROLIFTMAXTIMER:
3549 {
3550 ret = Hero.tliftclk * 10000;
3551 break;
3552 }
3553 case HEROLIFTHEIGHT:
3554 {
3555 ret = Hero.liftheight.getZLong();
3556 break;
3557 }
3558 case HEROHAMMERSTATE:
3559 {
3560 ret = Hero.getHammerState() * 10000;
3561 break;
3562 }
3563 case HEROFLICKERCOLOR:
3564 ret = (int32_t)(Hero.flickercolor) * 10000; break;
3565 case HEROFLASHINGCSET:
3566 136185 ret = (int32_t)(Hero.getFlashingCSet()) * 10000; break;
3567 case HEROFLICKERTRANSP:
3568 ret = (int32_t)(Hero.flickertransp) * 10000; break;
3569
3570 case HEROSLIDING:
3571 ret = Hero.sliding*10000; break;
3572 case HEROICECMB:
3573 ret = Hero.ice_combo*10000; break;
3574 case HEROSCRICECMB:
3575 ret = Hero.script_ice_combo*10000; break;
3576 case HEROICEVX:
3577 ret = Hero.ice_vx.getZLong(); break;
3578 case HEROICEVY:
3579 ret = Hero.ice_vy.getZLong(); break;
3580 case HEROICEENTRYFRAMES:
3581 ret = Hero.ice_entry_count*10000; break;
3582 case HEROICEENTRYMAXFRAMES:
3583 ret = Hero.ice_entry_mcount*10000; break;
3584
3585 ///----------------------------------------------------------------------------------------------------//
3586 //Input States
3587 case INPUTSTART:
3588 98023 ret=control_state[6]?10000:0;
3589 98023 break;
3590
3591 case INPUTMAP:
3592 4123 ret=control_state[9]?10000:0;
3593 4123 break;
3594
3595 case INPUTUP:
3596 5056867 ret=control_state[0]?10000:0;
3597 5056867 break;
3598
3599 case INPUTDOWN:
3600 4410418 ret=control_state[1]?10000:0;
3601 4410418 break;
3602
3603 case INPUTLEFT:
3604 4977391 ret=control_state[2]?10000:0;
3605 4977391 break;
3606
3607 case INPUTRIGHT:
3608 5016239 ret=control_state[3]?10000:0;
3609 5016239 break;
3610
3611 case INPUTA:
3612 11970574 ret=control_state[4]?10000:0;
3613 11970574 break;
3614
3615 case INPUTB:
3616 10596134 ret=control_state[5]?10000:0;
3617 10596134 break;
3618
3619 case INPUTL:
3620 6428754 ret=control_state[7]?10000:0;
3621 6428754 break;
3622
3623 case INPUTR:
3624 6424495 ret=control_state[8]?10000:0;
3625 6424495 break;
3626
3627 case INPUTEX1:
3628 122646 ret=control_state[10]?10000:0;
3629 122646 break;
3630
3631 case INPUTEX2:
3632 122937 ret=control_state[11]?10000:0;
3633 122937 break;
3634
3635 case INPUTEX3:
3636 23391 ret=control_state[12]?10000:0;
3637 23391 break;
3638
3639 case INPUTEX4:
3640 23391 ret=control_state[13]?10000:0;
3641 23391 break;
3642
3643 case INPUTAXISUP:
3644 ret=control_state[14]?10000:0;
3645 break;
3646
3647 case INPUTAXISDOWN:
3648 ret=control_state[15]?10000:0;
3649 break;
3650
3651 case INPUTAXISLEFT:
3652 ret=control_state[16]?10000:0;
3653 break;
3654
3655 case INPUTAXISRIGHT:
3656 ret=control_state[17]?10000:0;
3657 break;
3658
3659 case INPUTMOUSEX:
3660 {
3661 1054708 ret=get_mouse_state(0)*10000;
3662 1054708 break;
3663 }
3664
3665 case INPUTMOUSEY:
3666 {
3667 1318385 int32_t mousequakeoffset = 56+((int32_t)(zc::math::Sin((double)(quakeclk*int64_t(2)-frame))*4));
3668
3/4
✓ Branch 0 taken 40365 times.
✓ Branch 1 taken 1278020 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1278020 times.
1318385 int32_t tempoffset = (quakeclk > 0) ? mousequakeoffset : (get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
3669 1318385 ret=((get_mouse_state(1)-tempoffset))*10000;
3670 1318385 break;
3671 }
3672
3673 case INPUTMOUSEZ:
3674 ret=(get_mouse_state(2))*10000;
3675 break;
3676
3677 case INPUTMOUSEB:
3678 1073638 ret=(get_mouse_state(3))*10000;
3679 1073638 break;
3680
3681 case INPUTPRESSSTART:
3682 1102950 ret=button_press[6]?10000:0;
3683 1102950 break;
3684
3685 case INPUTPRESSMAP:
3686 335996 ret=button_press[9]?10000:0;
3687 335996 break;
3688
3689 case INPUTPRESSUP:
3690 2151876 ret=button_press[0]?10000:0;
3691 2151876 break;
3692
3693 case INPUTPRESSDOWN:
3694 1578611 ret=button_press[1]?10000:0;
3695 1578611 break;
3696
3697 case INPUTPRESSLEFT:
3698 1805665 ret=button_press[2]?10000:0;
3699 1805665 break;
3700
3701 case INPUTPRESSRIGHT:
3702 1291881 ret=button_press[3]?10000:0;
3703 1291881 break;
3704
3705 case INPUTPRESSA:
3706 4122120 ret=button_press[4]?10000:0;
3707 4122120 break;
3708
3709 case INPUTPRESSB:
3710 3447036 ret=button_press[5]?10000:0;
3711 3447036 break;
3712
3713 case INPUTPRESSL:
3714 3697426 ret=button_press[7]?10000:0;
3715 3697426 break;
3716
3717 case INPUTPRESSR:
3718 3481646 ret=button_press[8]?10000:0;
3719 3481646 break;
3720
3721 case INPUTPRESSEX1:
3722 1779092 ret=button_press[10]?10000:0;
3723 1779092 break;
3724
3725 case INPUTPRESSEX2:
3726 1349984 ret=button_press[11]?10000:0;
3727 1349984 break;
3728
3729 case INPUTPRESSEX3:
3730 833679 ret=button_press[12]?10000:0;
3731 833679 break;
3732
3733 case INPUTPRESSEX4:
3734 669416 ret=button_press[13]?10000:0;
3735 669416 break;
3736
3737 case PRESSAXISUP:
3738 ret=button_press[14]?10000:0;
3739 break;
3740
3741 case PRESSAXISDOWN:
3742 ret=button_press[15]?10000:0;
3743 break;
3744
3745 case PRESSAXISLEFT:
3746 ret=button_press[16]?10000:0;
3747 break;
3748
3749 case PRESSAXISRIGHT:
3750 ret=button_press[17]?10000:0;
3751 break;
3752
3753 case KEYMODIFIERS:
3754 {
3755 ret = (key_shifts*10000);
3756 break;
3757 }
3758
3759 ///----------------------------------------------------------------------------------------------------//
3760 //Itemdata Variables
3761
3762
3763 case IDATAUSEWPN:
3764 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3765 {
3766 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3767 ret = -10000;
3768 break;
3769 }
3770 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.imitate_weapon)*10000;
3771 break;
3772 case IDATAUSEDEF:
3773 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3774 {
3775 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3776 ret = -10000;
3777 break;
3778 }
3779 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.default_defense)*10000;
3780 break;
3781 case IDATAWRANGE:
3782 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3783 {
3784 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3785 ret = -10000;
3786 break;
3787 }
3788 ret=(itemsbuf[GET_REF(itemdataref)].weaprange)*10000;
3789 break;
3790 case IDATAMAGICTIMER:
3791 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3792 {
3793 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3794 ret = -10000;
3795 break;
3796 }
3797 ret=(itemsbuf[GET_REF(itemdataref)].magiccosttimer[0])*10000;
3798 break;
3799 case IDATAMAGICTIMER2:
3800 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3801 {
3802 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3803 ret = -10000;
3804 break;
3805 }
3806 ret=(itemsbuf[GET_REF(itemdataref)].magiccosttimer[1])*10000;
3807 break;
3808
3809 case IDATADURATION:
3810 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3811 {
3812 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3813 ret = -10000;
3814 break;
3815 }
3816 ret=(itemsbuf[GET_REF(itemdataref)].weapduration)*10000;
3817 break;
3818
3819 case IDATADUPLICATES:
3820 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3821 {
3822 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3823 ret = -10000;
3824 break;
3825 }
3826 ret=(itemsbuf[GET_REF(itemdataref)].duplicates)*10000;
3827 break;
3828 case IDATADRAWLAYER:
3829 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3830 {
3831 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3832 ret = -10000;
3833 break;
3834 }
3835 ret=(itemsbuf[GET_REF(itemdataref)].drawlayer)*10000;
3836 break;
3837 case IDATACOLLECTFLAGS:
3838 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3839 {
3840 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3841 ret = 0;
3842 break;
3843 }
3844 ret=(itemsbuf[GET_REF(itemdataref)].collectflags)*10000;
3845 break;
3846 case IDATAWEAPONSCRIPT:
3847 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3848 {
3849 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3850 ret = -10000;
3851 break;
3852 }
3853 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.script)*10000;
3854 break;
3855 case IDATAWEAPHXOFS:
3856 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3857 {
3858 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3859 ret = -10000;
3860 break;
3861 }
3862 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hxofs)*10000;
3863 break;
3864 case IDATAWEAPHYOFS:
3865 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3866 {
3867 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3868 ret = -10000;
3869 break;
3870 }
3871 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hyofs)*10000;
3872 break;
3873 case IDATAWEAPHXSZ:
3874 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3875 {
3876 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3877 ret = -10000;
3878 break;
3879 }
3880 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hxsz)*10000;
3881 break;
3882 case IDATAWEAPHYSZ:
3883 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3884 {
3885 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3886 ret = -10000;
3887 break;
3888 }
3889 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hysz)*10000;
3890 break;
3891 case IDATAWEAPHZSZ:
3892 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3893 {
3894 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3895 ret = -10000;
3896 break;
3897 }
3898 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.hzsz)*10000;
3899 break;
3900 case IDATAWEAPXOFS:
3901 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3902 {
3903 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3904 ret = -10000;
3905 break;
3906 }
3907 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.xofs)*10000;
3908 break;
3909 case IDATAWEAPYOFS:
3910 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3911 {
3912 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3913 ret = -10000;
3914 break;
3915 }
3916 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.yofs)*10000;
3917 break;
3918 case IDATAHXOFS:
3919 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3920 {
3921 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3922 ret = -10000;
3923 break;
3924 }
3925 ret=(itemsbuf[GET_REF(itemdataref)].hxofs)*10000;
3926 break;
3927 case IDATAHYOFS:
3928 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3929 {
3930 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3931 ret = -10000;
3932 break;
3933 }
3934 ret=(itemsbuf[GET_REF(itemdataref)].hyofs)*10000;
3935 break;
3936 case IDATAHXSZ:
3937 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3938 {
3939 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3940 ret = -10000;
3941 break;
3942 }
3943 ret=(itemsbuf[GET_REF(itemdataref)].hxsz)*10000;
3944 break;
3945 case IDATAHYSZ:
3946 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3947 {
3948 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3949 ret = -10000;
3950 break;
3951 }
3952 ret=(itemsbuf[GET_REF(itemdataref)].hysz)*10000;
3953 break;
3954 case IDATAHZSZ:
3955 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3956 {
3957 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3958 ret = -10000;
3959 break;
3960 }
3961 ret=(itemsbuf[GET_REF(itemdataref)].hzsz)*10000;
3962 break;
3963 case IDATADXOFS:
3964 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3965 {
3966 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3967 ret = -10000;
3968 break;
3969 }
3970 ret=(itemsbuf[GET_REF(itemdataref)].xofs)*10000;
3971 break;
3972 case IDATADYOFS:
3973 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3974 {
3975 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3976 ret = -10000;
3977 break;
3978 }
3979 ret=(itemsbuf[GET_REF(itemdataref)].yofs)*10000;
3980 break;
3981 case IDATATILEW:
3982 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3983 {
3984 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3985 ret = -10000;
3986 break;
3987 }
3988 ret=(itemsbuf[GET_REF(itemdataref)].tilew)*10000;
3989 break;
3990 case IDATATILEH:
3991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
53 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
3992 {
3993 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
3994 ret = -10000;
3995 break;
3996 }
3997 53 ret=(itemsbuf[GET_REF(itemdataref)].tileh)*10000;
3998 53 break;
3999 case IDATAPICKUP:
4000 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4001 {
4002 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4003 ret = -10000;
4004 break;
4005 }
4006 ret=(itemsbuf[GET_REF(itemdataref)].pickup)*10000;
4007 break;
4008 case IDATAOVERRIDEFL:
4009 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4010 {
4011 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4012 ret = 0;
4013 break;
4014 }
4015 ret=(itemsbuf[GET_REF(itemdataref)].overrideFLAGS)*10000;
4016 break;
4017
4018 case IDATATILEWWEAP:
4019 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4020 {
4021 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4022 ret = -10000;
4023 break;
4024 }
4025 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.tilew)*10000;
4026 break;
4027 case IDATATILEHWEAP:
4028 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4029 {
4030 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4031 ret = -10000;
4032 break;
4033 }
4034 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.tileh)*10000;
4035 break;
4036 case IDATAOVERRIDEFLWEAP:
4037 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4038 {
4039 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4040 ret = 0;
4041 break;
4042 }
4043 ret=(itemsbuf[GET_REF(itemdataref)].weap_data.override_flags)*10000;
4044 break;
4045
4046 case IDATATYPE:
4047
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58309993 times.
58309993 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4048 {
4049 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4050 ret = -10000;
4051 break;
4052 }
4053 58309993 ret=(itemsbuf[GET_REF(itemdataref)].type)*10000;
4054 58309993 break;
4055
4056 case IDATALEVEL:
4057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 668845 times.
668845 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4058 {
4059 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4060 ret = -10000;
4061 break;
4062 }
4063 668845 ret=(itemsbuf[GET_REF(itemdataref)].level)*10000;
4064 668845 break;
4065
4066 case IDATAKEEP:
4067 3 ret = item_flag(item_gamedata);
4068 3 break;
4069
4070 case IDATAAMOUNT:
4071 {
4072 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4073 {
4074 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4075 ret = -10000;
4076 break;
4077 }
4078 int32_t v = itemsbuf[GET_REF(itemdataref)].amount;
4079 ret = ((v&0x4000)?-1:1)*(v & 0x3FFF)*10000;
4080 break;
4081 }
4082 case IDATAGRADUAL:
4083 {
4084 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4085 {
4086 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4087 ret = -10000;
4088 break;
4089 }
4090 ret = (itemsbuf[GET_REF(itemdataref)].amount&0x8000) ? 10000 : 0;
4091 break;
4092 }
4093 case IDATACONSTSCRIPT:
4094 ret = item_flag(item_passive_script);
4095 break;
4096 case IDATASSWIMDISABLED:
4097 ret = item_flag(item_sideswim_disabled);
4098 break;
4099 case IDATABUNNYABLE:
4100 ret = item_flag(item_bunny_enabled);
4101 break;
4102 case IDATAJINXIMMUNE:
4103 ret = item_flag(item_jinx_immune);
4104 break;
4105 case IDATAJINXSWAP:
4106 ret = item_flag(item_flip_jinx);
4107 break;
4108 case IDATAUSEBURNSPR:
4109 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4110 {
4111 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4112 ret = 0;
4113 }
4114 else ret = (itemsbuf[GET_REF(itemdataref)].weap_data.wflags & WFLAG_UPDATE_IGNITE_SPRITE) ? 10000 : 0;
4115 break;
4116
4117 case IDATASETMAX:
4118 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4119 {
4120 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4121 ret = -10000;
4122 break;
4123 }
4124 ret=(itemsbuf[GET_REF(itemdataref)].setmax)*10000;
4125 break;
4126
4127 case IDATAMAX:
4128 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4129 {
4130 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4131 ret = -10000;
4132 break;
4133 }
4134 ret=(itemsbuf[GET_REF(itemdataref)].max)*10000;
4135 break;
4136
4137 case IDATACOUNTER:
4138 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4139 {
4140 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4141 ret = -10000;
4142 break;
4143 }
4144 ret=(itemsbuf[GET_REF(itemdataref)].count)*10000;
4145 break;
4146
4147 case IDATAPSOUND:
4148 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4149 {
4150 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4151 ret = -10000;
4152 break;
4153 }
4154 ret=(itemsbuf[GET_REF(itemdataref)].playsound)*10000;
4155 break;
4156 case IDATAUSESOUND:
4157 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4158 {
4159 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4160 ret = -10000;
4161 break;
4162 }
4163 ret=(itemsbuf[GET_REF(itemdataref)].usesound)*10000;
4164 break;
4165
4166 case IDATAUSESOUND2:
4167 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4168 {
4169 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4170 ret = -10000;
4171 break;
4172 }
4173 ret=(itemsbuf[GET_REF(itemdataref)].usesound2)*10000;
4174 break;
4175
4176 case IDATAPOWER:
4177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1994 times.
1994 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4178 {
4179 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4180 ret = -10000;
4181 break;
4182 }
4183 1994 ret=(itemsbuf[GET_REF(itemdataref)].power)*10000;
4184 1994 break;
4185
4186 //Get the ID of an item.
4187 case IDATAID:
4188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1918 times.
1918 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4189 {
4190 ret = -10000;
4191 break;
4192 }
4193 1918 ret=GET_REF(itemdataref)*10000;
4194 1918 break;
4195
4196 //Get the script assigned to an item (active)
4197 case IDATASCRIPT:
4198 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4199 {
4200 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4201 ret = -10000;
4202 break;
4203 }
4204 ret=(itemsbuf[GET_REF(itemdataref)].script)*10000;
4205 break;
4206 case IDATASPRSCRIPT:
4207 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4208 {
4209 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4210 ret = -10000;
4211 break;
4212 }
4213 ret=(itemsbuf[GET_REF(itemdataref)].sprite_script)*10000;
4214 break;
4215 //Hero TIle modifier
4216 case IDATALTM:
4217 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4218 {
4219 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4220 ret = 0;
4221 break;
4222 }
4223 ret=(itemsbuf[GET_REF(itemdataref)].ltm)*10000;
4224 break;
4225 //Pickup script
4226 case IDATAPSCRIPT:
4227 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4228 {
4229 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4230 ret = -10000;
4231 break;
4232 }
4233 ret=(itemsbuf[GET_REF(itemdataref)].collect_script)*10000;
4234 break;
4235 //Pickup string
4236 case IDATAPSTRING:
4237 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4238 {
4239 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4240 ret = -10000;
4241 break;
4242 }
4243 ret=(itemsbuf[GET_REF(itemdataref)].pstring)*10000;
4244 break;
4245 case IDATAPFLAGS:
4246 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4247 {
4248 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4249 ret = 0;
4250 break;
4251 }
4252 ret = (itemsbuf[GET_REF(itemdataref)].pickup_string_flags)*10000;
4253 break;
4254 case IDATAPICKUPLITEMS:
4255 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4256 {
4257 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4258 ret = 0;
4259 break;
4260 }
4261 ret = (itemsbuf[GET_REF(itemdataref)].pickup_litems)*10000;
4262 break;
4263 case IDATAPICKUPLITEMLEVEL:
4264 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4265 {
4266 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4267 ret = 0;
4268 break;
4269 }
4270 ret = (itemsbuf[GET_REF(itemdataref)].pickup_litem_level)*10000;
4271 break;
4272 //Magic cost
4273 case IDATAMAGCOST:
4274 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4275 {
4276 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4277 ret = -10000;
4278 break;
4279 }
4280 ret=(itemsbuf[GET_REF(itemdataref)].cost_amount[0])*10000;
4281 break;
4282 case IDATACOST2:
4283 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4284 {
4285 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4286 ret = -10000;
4287 break;
4288 }
4289 ret=(itemsbuf[GET_REF(itemdataref)].cost_amount[1])*10000;
4290 break;
4291 case IDATACOOLDOWN:
4292 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4293 {
4294 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4295 ret = -10000;
4296 break;
4297 }
4298 ret = (itemsbuf[GET_REF(itemdataref)].cooldown) * 10000;
4299 break;
4300 //cost counter ref
4301 case IDATACOSTCOUNTER:
4302 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4303 {
4304 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4305 ret = -10000;
4306 break;
4307 }
4308 ret=(itemsbuf[GET_REF(itemdataref)].cost_counter[0])*10000;
4309 break;
4310 case IDATACOSTCOUNTER2:
4311 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4312 {
4313 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4314 ret = -10000;
4315 break;
4316 }
4317 ret=(itemsbuf[GET_REF(itemdataref)].cost_counter[1])*10000;
4318 break;
4319 //Min Hearts to Pick Up
4320 case IDATAMINHEARTS:
4321 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4322 {
4323 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4324 ret = -10000;
4325 break;
4326 }
4327 ret=(itemsbuf[GET_REF(itemdataref)].pickup_hearts)*10000;
4328 break;
4329 //Tile used by the item
4330 case IDATATILE:
4331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55709 times.
55709 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4332 {
4333 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4334 ret = -10000;
4335 break;
4336 }
4337 55709 ret=(itemsbuf[GET_REF(itemdataref)].tile)*10000;
4338 55709 break;
4339 //itemdata->Flash
4340 case IDATAMISC:
4341 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4342 {
4343 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4344 ret = -10000;
4345 break;
4346 }
4347 ret=(itemsbuf[GET_REF(itemdataref)].misc_flags)*10000;
4348 break;
4349 //->CSet
4350 case IDATACSET:
4351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55684 times.
55684 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4352 {
4353 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4354 ret = -10000;
4355 break;
4356 }
4357
4358 55684 ret = (itemsbuf[GET_REF(itemdataref)].csets&15)*10000;
4359
4360 // If we find quests that broke, use this code.
4361 // if (QHeader.compareVer(2, 55, 9) >= 0)
4362 // ret = (itemsbuf[ri->idata].csets&15)*10000;
4363 // else
4364 // ret = itemsbuf[ri->idata].csets*10000;
4365 55684 break;
4366 case IDATAFLASHCSET:
4367 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4368 {
4369 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4370 ret = -10000;
4371 break;
4372 }
4373 ret=(itemsbuf[GET_REF(itemdataref)].csets>>4)*10000;
4374 break;
4375 //->A.Frames
4376 case IDATAFRAMES:
4377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63041 times.
63041 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4378 {
4379 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4380 ret = -10000;
4381 break;
4382 }
4383 63041 ret=(itemsbuf[GET_REF(itemdataref)].frames)*10000;
4384 63041 break;
4385 /*
4386 case IDATAFRAME:
4387 ret=(itemsbuf[ri->idata].frame)*10000;
4388 break;
4389 */
4390 //->A.Speed
4391 case IDATAASPEED:
4392
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142873 times.
142873 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4393 {
4394 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4395 ret = -10000;
4396 break;
4397 }
4398 142873 ret=(itemsbuf[GET_REF(itemdataref)].speed)*10000;
4399 142873 break;
4400 //->Delay
4401 case IDATADELAY:
4402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74538 times.
74538 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
4403 {
4404 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
4405 ret = -10000;
4406 break;
4407 }
4408 74538 ret=(itemsbuf[GET_REF(itemdataref)].delay)*10000;
4409 74538 break;
4410 // teo of this item upgrades
4411 case IDATACOMBINE:
4412 ret = item_flag(item_combine);
4413 break;
4414 //Use item, and get the lower level one
4415 case IDATADOWNGRADE:
4416 ret = item_flag(item_downgrade);
4417 break;
4418 //Only validate the cost, don't charge it
4419 case IDATAVALIDATE:
4420 ret = item_flag(item_validate_only);
4421 break;
4422 case IDATAVALIDATE2:
4423 ret = item_flag(item_validate_only_2);
4424 break;
4425 //->Keep Old
4426 case IDATAKEEPOLD:
4427 ret = item_flag(item_keep_old);
4428 break;
4429 //Use rupees instead of magic
4430 case IDATARUPEECOST:
4431 ret = item_flag(item_rupee_magic);
4432 break;
4433 //Can be eaten
4434 case IDATAEDIBLE:
4435 ret = item_flag(item_edible);
4436 break;
4437 //currently unused
4438 case IDATAFLAGUNUSED:
4439 ret = item_flag(item_unused);
4440 break;
4441 //Gain lower level items when collected
4442 case IDATAGAINLOWER:
4443 ret = item_flag(item_gain_old);
4444 break;
4445
4446 ///----------------------------------------------------------------------------------------------------//
4447 //LWeapon Variables
4448 case LWPNSPECIAL:
4449 if(auto s=checkLWpn(GET_REF(lwpnref)))
4450 ret=((int32_t)s->specialinfo)*10000;
4451
4452
4453 break;
4454
4455 case LWPNSCALE:
4456 if ( get_qr(qr_OLDSPRITEDRAWS) )
4457 {
4458 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
4459 ret = -1; break;
4460 }
4461 if(auto s=checkLWpn(GET_REF(lwpnref)))
4462 ret=((int32_t)s->scale)*100.0;
4463
4464 break;
4465
4466 case LWPNX:
4467
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 939265 times.
954757 if(auto s=checkLWpn(GET_REF(lwpnref)))
4468 {
4469
2/2
✓ Branch 0 taken 350528 times.
✓ Branch 1 taken 588737 times.
939265 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
4470 {
4471 350528 ret=(s->x).getZLong();
4472 350528 }
4473 else
4474 588737 ret=((int32_t)s->x)*10000;
4475 939265 }
4476
4477 954757 break;
4478
4479 case SPRITEMAXLWPN:
4480 {
4481 //No bounds check, as this is a universal function and works from NULL pointers!
4482 ret = Lwpns.getMax() * 10000;
4483 break;
4484 }
4485
4486 case LWPNY:
4487
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 934658 times.
950150 if(auto s=checkLWpn(GET_REF(lwpnref)))
4488 {
4489
2/2
✓ Branch 0 taken 350395 times.
✓ Branch 1 taken 584263 times.
934658 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
4490 {
4491 350395 ret=(s->y).getZLong();
4492 350395 }
4493 else
4494 584263 ret=((int32_t)s->y)*10000;
4495 934658 }
4496 950150 break;
4497
4498 case LWPNZ:
4499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109736 times.
109736 if(auto s=checkLWpn(GET_REF(lwpnref)))
4500 {
4501
2/2
✓ Branch 0 taken 53984 times.
✓ Branch 1 taken 55752 times.
109736 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
4502 {
4503 53984 ret=(s->z).getZLong();
4504 53984 }
4505 else
4506 55752 ret=((int32_t)s->z)*10000;
4507 109736 }
4508
4509 109736 break;
4510
4511 case LWPNJUMP:
4512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4513 {
4514 6 ret = s->fall.getZLong() / -100;
4515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (get_qr(qr_SPRITE_JUMP_IS_TRUNCATED)) ret = trunc(ret / 10000) * 10000;
4516 6 }
4517
4518 6 break;
4519
4520 case LWPNFAKEJUMP:
4521 if(auto s=checkLWpn(GET_REF(lwpnref)))
4522 {
4523 ret = s->fakefall.getZLong() / -100;
4524 if (get_qr(qr_SPRITE_JUMP_IS_TRUNCATED)) ret = trunc(ret / 10000) * 10000;
4525 }
4526
4527 break;
4528
4529 case LWPNDIR:
4530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80933 times.
80933 if(auto s=checkLWpn(GET_REF(lwpnref)))
4531 80933 ret=s->dir*10000;
4532
4533 80933 break;
4534
4535 case LWPNGRAVITY:
4536 if(auto s=checkLWpn(GET_REF(lwpnref)))
4537 ret= (s->moveflags & move_obeys_grav) ? 10000 : 0;
4538
4539 break;
4540
4541 case LWPNSTEP:
4542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5388 times.
5388 if(auto s=checkLWpn(GET_REF(lwpnref)))
4543 {
4544
3/4
✓ Branch 0 taken 1140 times.
✓ Branch 1 taken 4248 times.
✓ Branch 2 taken 1140 times.
✗ Branch 3 not taken.
5388 if ( get_qr(qr_STEP_IS_FLOAT) || replay_is_active() )
4545 {
4546 5388 ret=s->step.getZLong() * 100;
4547 5388 }
4548 //old, buggy code replication, round two: Go! -Z
4549 //else ret = ( ( ( s->step ) * 100.0 ).getZLong() );
4550
4551 //else
4552 //{
4553 //old, buggy code replication, round THREE: Go! -Z
4554 // double tmp = ( s->step.getFloat() ) * 1000000.0;
4555 // ret = (int32_t)tmp;
4556 //}
4557
4558 //old, buggy code replication, round FOUR: Go! -Z
4559 else ret = (int32_t)((float)s->step * 1000000.0);
4560 5388 }
4561 5388 break;
4562
4563 case LWPNANGLE:
4564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 416 times.
416 if(auto s=checkLWpn(GET_REF(lwpnref)))
4565 416 ret=(int32_t)(s->angle*10000);
4566
4567 416 break;
4568
4569 case LWPNDEGANGLE:
4570 if(auto s=checkLWpn(GET_REF(lwpnref)))
4571 {
4572 ret=(int32_t)(s->angle*(180.0 / PI)*10000);
4573 }
4574
4575 break;
4576
4577 case LWPNVX:
4578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 246 times.
246 if(auto s=checkLWpn(GET_REF(lwpnref)))
4579 {
4580
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 246 times.
246 if (s->angular)
4581 ret = int32_t(zc::math::Cos(s->angle)*10000.0*s->step);
4582 else
4583 {
4584
4/7
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 246 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 122 times.
✓ Branch 6 taken 124 times.
246 switch(NORMAL_DIR(s->dir))
4585 {
4586 case l_up:
4587 case l_down:
4588 case left:
4589 ret = int32_t(-10000.0*s->step);
4590 break;
4591
4592 case r_down:
4593 case r_up:
4594 case right:
4595 122 ret = int32_t(10000.0*s->step);
4596 122 break;
4597
4598 default:
4599 124 ret = 0;
4600 124 break;
4601 }
4602 }
4603 246 }
4604
4605 246 break;
4606
4607 case LWPNVY:
4608 if(auto s=checkLWpn(GET_REF(lwpnref)))
4609 {
4610 if (s->angular)
4611 ret = int32_t(zc::math::Sin(s->angle)*10000.0*s->step);
4612 else
4613 {
4614 switch(NORMAL_DIR(s->dir))
4615 {
4616 case l_up:
4617 case r_up:
4618 case up:
4619 ret = int32_t(-10000.0*s->step);
4620 break;
4621 case l_down:
4622 case r_down:
4623 case down:
4624 ret = int32_t(10000.0*s->step);
4625 break;
4626
4627 default:
4628 ret = 0;
4629 break;
4630 }
4631 }
4632 }
4633
4634 break;
4635
4636 case LWPNANGULAR:
4637
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4638 6 ret=s->angular*10000;
4639
4640 6 break;
4641
4642 case LWPNAUTOROTATE:
4643 if(auto s=checkLWpn(GET_REF(lwpnref)))
4644 ret=s->autorotate*10000;
4645
4646 break;
4647
4648 case LWPNBEHIND:
4649 if(auto s=checkLWpn(GET_REF(lwpnref)))
4650 ret=s->behind*10000;
4651
4652 break;
4653
4654 case LWPNDRAWTYPE:
4655
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4656 6 ret=s->drawstyle*10000;
4657
4658 6 break;
4659
4660 case LWPNPOWER:
4661
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 104530 times.
104531 if(auto s=checkLWpn(GET_REF(lwpnref)))
4662 104530 ret=s->power*10000;
4663
4664 104531 break;
4665
4666 case LWPNDEAD:
4667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8339 times.
8339 if(auto s=checkLWpn(GET_REF(lwpnref)))
4668 8339 ret=s->dead*10000;
4669
4670 8339 break;
4671
4672 case LWPNTYPE:
4673
2/2
✓ Branch 0 taken 16620 times.
✓ Branch 1 taken 4500566 times.
4517186 if(auto s=checkLWpn(GET_REF(lwpnref)))
4674 4500566 ret=s->id*10000;
4675
4676 4517186 break;
4677
4678 case LWPNTILE:
4679
1/2
✓ Branch 0 taken 53697 times.
✗ Branch 1 not taken.
53697 if(auto s=checkLWpn(GET_REF(lwpnref)))
4680 53697 ret=s->tile*10000;
4681
4682 53697 break;
4683
4684 case LWPNSCRIPTTILE:
4685
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 586 times.
586 if(auto s=checkLWpn(GET_REF(lwpnref)))
4686 586 ret=s->scripttile*10000;
4687
4688 586 break;
4689
4690 case LWPNSCRIPTFLIP:
4691 if(auto s=checkLWpn(GET_REF(lwpnref)))
4692 ret=s->scriptflip*10000;
4693
4694 break;
4695
4696 case LWPNCSET:
4697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53381 times.
53381 if(auto s=checkLWpn(GET_REF(lwpnref)))
4698 53381 ret=s->cs*10000;
4699
4700 53381 break;
4701
4702 case LWPNFLASHCSET:
4703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 220 times.
220 if(auto s=checkLWpn(GET_REF(lwpnref)))
4704 220 ret=(s->o_cset>>4)*10000;
4705
4706 220 break;
4707
4708 case LWPNFRAMES:
4709
1/2
✓ Branch 0 taken 4362 times.
✗ Branch 1 not taken.
4362 if(auto s=checkLWpn(GET_REF(lwpnref)))
4710 4362 ret=s->frames*10000;
4711
4712 4362 break;
4713
4714 case LWPNFRAME:
4715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4716 6 ret=s->aframe*10000;
4717
4718 6 break;
4719
4720 case LWPNASPEED:
4721
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4622 times.
4622 if(auto s=checkLWpn(GET_REF(lwpnref)))
4722 4622 ret=s->o_speed*10000;
4723
4724 4622 break;
4725
4726 case LWPNFLASH:
4727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4728 6 ret=s->flash*10000;
4729
4730 6 break;
4731
4732 case LWPNFLIP:
4733 if(auto s=checkLWpn(GET_REF(lwpnref)))
4734 ret=s->flip*10000;
4735
4736 break;
4737
4738 case LWPNCOUNT:
4739 2001860 ret=Lwpns.Count()*10000;
4740 2001860 break;
4741
4742 case LWPNEXTEND:
4743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4744 6 ret=s->extend*10000;
4745
4746 6 break;
4747
4748 case LWPNOTILE:
4749
1/2
✓ Branch 0 taken 835937 times.
✗ Branch 1 not taken.
835937 if(auto s=checkLWpn(GET_REF(lwpnref)))
4750 835937 ret=s->o_tile*10000;
4751
4752 835937 break;
4753
4754 case LWPNOCSET:
4755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23909 times.
23909 if(auto s=checkLWpn(GET_REF(lwpnref)))
4756 23909 ret=(s->o_cset&15)*10000;
4757
4758 23909 break;
4759
4760 case LWPNHXOFS:
4761
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 284226 times.
299718 if(auto s=checkLWpn(GET_REF(lwpnref)))
4762 284226 ret=(s->hxofs)*10000;
4763
4764 299718 break;
4765
4766 case LWPNHYOFS:
4767
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 281478 times.
296970 if(auto s=checkLWpn(GET_REF(lwpnref)))
4768 281478 ret=(s->hyofs)*10000;
4769
4770 296970 break;
4771
4772 case LWPNXOFS:
4773
1/2
✓ Branch 0 taken 10231 times.
✗ Branch 1 not taken.
10231 if(auto s=checkLWpn(GET_REF(lwpnref)))
4774 10231 ret=((int32_t)(s->xofs))*10000;
4775
4776 10231 break;
4777
4778 case LWPNYOFS:
4779
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11477 times.
11477 if(auto s=checkLWpn(GET_REF(lwpnref)))
4780
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11477 times.
11477 ret=((int32_t)(s->yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)))*10000;
4781
4782 11477 break;
4783
4784 case LWPNSHADOWXOFS:
4785 if(auto s=checkLWpn(GET_REF(lwpnref)))
4786 ret=((int32_t)(s->shadowxofs))*10000;
4787
4788 break;
4789
4790 case LWPNSHADOWYOFS:
4791 if(auto s=checkLWpn(GET_REF(lwpnref)))
4792 ret=((int32_t)(s->shadowyofs))*10000;
4793
4794 break;
4795
4796 case LWPNTOTALDYOFFS:
4797 if(auto s=checkLWpn(GET_REF(lwpnref)))
4798 ret = ((int32_t)(s->yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset))
4799 + ((s->switch_hooked && Hero.switchhookstyle == swRISE)
4800 ? -(8-(abs(Hero.switchhookclk-32)/4)) : 0)) * 10000;
4801 break;
4802
4803 case LWPNZOFS:
4804
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
4805 6 ret=((int32_t)(s->zofs))*10000;
4806
4807 6 break;
4808
4809 case LWPNHXSZ:
4810
2/2
✓ Branch 0 taken 15492 times.
✓ Branch 1 taken 267550 times.
283042 if(auto s=checkLWpn(GET_REF(lwpnref)))
4811 267550 ret=(s->hit_width)*10000;
4812
4813 283042 break;
4814
4815 case LWPNHYSZ:
4816
2/2
✓ Branch 0 taken 269504 times.
✓ Branch 1 taken 15492 times.
284996 if(auto s=checkLWpn(GET_REF(lwpnref)))
4817 269504 ret=(s->hit_height)*10000;
4818
4819 284996 break;
4820
4821 case LWPNHZSZ:
4822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36540 times.
36540 if(auto s=checkLWpn(GET_REF(lwpnref)))
4823 36540 ret=(s->hzsz)*10000;
4824
4825 36540 break;
4826
4827 case LWPNTXSZ:
4828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32019 times.
32019 if(auto s=checkLWpn(GET_REF(lwpnref)))
4829 32019 ret=(s->txsz)*10000;
4830
4831 32019 break;
4832
4833 case LWPNTYSZ:
4834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32019 times.
32019 if(auto s=checkLWpn(GET_REF(lwpnref)))
4835 32019 ret=(s->tysz)*10000;
4836
4837 32019 break;
4838
4839 case LWPNCOLLDET:
4840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5469 times.
5469 if(auto s=checkLWpn(GET_REF(lwpnref)))
4841 5469 ret=(s->scriptcoldet)*10000;
4842
4843 5469 break;
4844
4845 case LWPNENGINEANIMATE:
4846 if(auto s=checkLWpn(GET_REF(lwpnref)))
4847 ret=(s->do_animation)*10000;
4848
4849 break;
4850
4851 case LWPNPARENT:
4852
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2166 times.
2166 if(auto s=checkLWpn(GET_REF(lwpnref)))
4853 2166 ret=(s->parentitem)*10000;
4854
4855 2166 break;
4856
4857 case LWPNLEVEL:
4858 if(auto s=checkLWpn(GET_REF(lwpnref)))
4859 ret=(s->level)*10000;
4860
4861 break;
4862
4863 case LWPNSCRIPT:
4864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(auto s=checkLWpn(GET_REF(lwpnref)))
4865 3 ret=(s->script)*10000;
4866
4867 3 break;
4868
4869 case LWPNUSEWEAPON:
4870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60075 times.
60075 if(auto s=checkLWpn(GET_REF(lwpnref)))
4871 60075 ret=(s->useweapon)*10000;
4872
4873 60075 break;
4874
4875 case LWPNUSEDEFENCE:
4876 if(auto s=checkLWpn(GET_REF(lwpnref)))
4877 ret=(s->usedefense)*10000;
4878
4879 break;
4880
4881 case LWEAPONSCRIPTUID:
4882 if(auto s=checkLWpn(GET_REF(lwpnref)))
4883 ret=(s->getUID());
4884
4885 break;
4886
4887 case LWPNROTATION:
4888 if ( get_qr(qr_OLDSPRITEDRAWS) )
4889 {
4890 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
4891 ret = -1; break;
4892 }
4893 if(auto s=checkLWpn(GET_REF(lwpnref)))
4894 ret=s->rotation*10000;
4895
4896 break;
4897
4898 case LWPNFALLCLK:
4899
1/2
✓ Branch 0 taken 1552 times.
✗ Branch 1 not taken.
1552 if(auto s=checkLWpn(GET_REF(lwpnref)))
4900 {
4901 1552 ret = s->fallclk * 10000;
4902 1552 }
4903 1552 break;
4904
4905 case LWPNFALLCMB:
4906 if(auto s=checkLWpn(GET_REF(lwpnref)))
4907 {
4908 ret = s->fallCombo * 10000;
4909 }
4910 break;
4911
4912 case LWPNDROWNCLK:
4913 if(auto s=checkLWpn(GET_REF(lwpnref)))
4914 {
4915 ret = s->drownclk * 10000;
4916 }
4917 break;
4918
4919 case LWPNDROWNCMB:
4920 if(auto s=checkLWpn(GET_REF(lwpnref)))
4921 {
4922 ret = s->drownCombo * 10000;
4923 }
4924 break;
4925
4926 case LWPNFAKEZ:
4927 if(auto s=checkLWpn(GET_REF(lwpnref)))
4928 {
4929 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
4930 {
4931 ret=(s->fakez).getZLong();
4932 }
4933 else
4934 ret=((int32_t)s->fakez)*10000;
4935 }
4936 break;
4937
4938 case LWPNGLOWRAD:
4939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48553 times.
48553 if(auto s=checkLWpn(GET_REF(lwpnref)))
4940 {
4941 48553 ret = s->glowRad * 10000;
4942 48553 }
4943 48553 break;
4944
4945 case LWPNGLOWSHP:
4946 if(auto s=checkLWpn(GET_REF(lwpnref)))
4947 {
4948 ret = s->glowShape * 10000;
4949 }
4950 break;
4951
4952 case LWPNUNBL:
4953 if(auto s=checkLWpn(GET_REF(lwpnref)))
4954 {
4955 ret = s->unblockable * 10000;
4956 }
4957 break;
4958
4959 case LWPNSHADOWSPR:
4960 if(auto s=checkLWpn(GET_REF(lwpnref)))
4961 {
4962 ret = s->spr_shadow * 10000;
4963 }
4964 break;
4965 case LWSWHOOKED:
4966 if(auto s=checkLWpn(GET_REF(lwpnref)))
4967 {
4968 ret = s->switch_hooked ? 10000 : 0;
4969 }
4970 break;
4971 case LWPNTIMEOUT:
4972 if(auto s=checkLWpn(GET_REF(lwpnref)))
4973 {
4974 ret = s->weap_timeout * 10000;
4975 }
4976 break;
4977 case LWPNDEATHITEM:
4978 if(auto s=checkLWpn(GET_REF(lwpnref)))
4979 {
4980 ret = s->death_spawnitem * 10000;
4981 }
4982 break;
4983 case LWPNDEATHDROPSET:
4984 if(auto s=checkLWpn(GET_REF(lwpnref)))
4985 {
4986 ret = s->death_spawndropset * 10000;
4987 }
4988 break;
4989 case LWPNDEATHIPICKUP:
4990 if(auto s=checkLWpn(GET_REF(lwpnref)))
4991 {
4992 ret = s->death_item_pflags * 10000;
4993 }
4994 break;
4995 case LWPNDEATHSPRITE:
4996 if(auto s=checkLWpn(GET_REF(lwpnref)))
4997 {
4998 ret = s->death_sprite * 10000;
4999 }
5000 break;
5001 case LWPNDEATHSFX:
5002 if(auto s=checkLWpn(GET_REF(lwpnref)))
5003 {
5004 ret = s->death_sfx * 10000;
5005 }
5006 break;
5007 case LWPNLIFTLEVEL:
5008 if(auto s=checkLWpn(GET_REF(lwpnref)))
5009 {
5010 ret = s->lift_level * 10000;
5011 }
5012 break;
5013 case LWPNLIFTTIME:
5014 if(auto s=checkLWpn(GET_REF(lwpnref)))
5015 {
5016 ret = s->lift_time * 10000;
5017 }
5018 break;
5019 case LWPNLIFTHEIGHT:
5020 if(auto s=checkLWpn(GET_REF(lwpnref)))
5021 {
5022 ret = s->lift_height.getZLong();
5023 }
5024 break;
5025
5026 ///----------------------------------------------------------------------------------------------------//
5027 //EWeapon Variables
5028 case EWPNSCALE:
5029 if ( get_qr(qr_OLDSPRITEDRAWS) )
5030 {
5031 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
5032 ret = -1; break;
5033 }
5034 if(auto s=checkEWpn(GET_REF(ewpnref)))
5035 ret=((int32_t)s->scale)*100.0;
5036
5037 break;
5038
5039 case EWPNX:
5040
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4354592 times.
4354592 if(auto s=checkEWpn(GET_REF(ewpnref)))
5041 {
5042
2/2
✓ Branch 0 taken 219464 times.
✓ Branch 1 taken 4135128 times.
4354592 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
5043 {
5044 219464 ret=(s->x).getZLong();
5045 219464 }
5046 else
5047 4135128 ret=((int32_t)s->x)*10000;
5048 4354592 }
5049 4354592 break;
5050
5051 case SPRITEMAXEWPN:
5052 {
5053 //No bounds check, as this is a universal function and works from NULL pointers!
5054 ret = Ewpns.getMax() * 10000;
5055 break;
5056 }
5057
5058 case EWPNY:
5059
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4354690 times.
4354690 if(auto s=checkEWpn(GET_REF(ewpnref)))
5060 {
5061
2/2
✓ Branch 0 taken 219317 times.
✓ Branch 1 taken 4135373 times.
4354690 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
5062 {
5063 219317 ret=(s->y).getZLong();
5064 219317 }
5065 else
5066 4135373 ret=((int32_t)s->y)*10000;
5067 4354690 }
5068 4354690 break;
5069
5070 case EWPNZ:
5071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552907 times.
552907 if(auto s=checkEWpn(GET_REF(ewpnref)))
5072 {
5073
2/2
✓ Branch 0 taken 1432 times.
✓ Branch 1 taken 551475 times.
552907 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
5074 {
5075 1432 ret=(s->z).getZLong();
5076 1432 }
5077 else
5078 551475 ret=((int32_t)s->z)*10000;
5079 552907 }
5080 552907 break;
5081
5082 case EWPNJUMP:
5083 if(auto s=checkEWpn(GET_REF(ewpnref)))
5084 {
5085 ret = s->fall.getZLong() / -100;
5086 if (get_qr(qr_SPRITE_JUMP_IS_TRUNCATED)) ret = trunc(ret / 10000) * 10000;
5087 }
5088
5089 break;
5090
5091 case EWPNFAKEJUMP:
5092 if(auto s=checkEWpn(GET_REF(ewpnref)))
5093 {
5094 ret = s->fakefall.getZLong() / -100;
5095 if (get_qr(qr_SPRITE_JUMP_IS_TRUNCATED)) ret = trunc(ret / 10000) * 10000;
5096 }
5097
5098 break;
5099
5100 case EWPNDIR:
5101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61563 times.
61563 if(auto s=checkEWpn(GET_REF(ewpnref)))
5102 61563 ret=s->dir*10000;
5103
5104 61563 break;
5105
5106 case EWPNLEVEL:
5107
1/2
✓ Branch 0 taken 2845 times.
✗ Branch 1 not taken.
2845 if(auto s=checkEWpn(GET_REF(ewpnref)))
5108 2845 ret=s->level*10000;
5109
5110 2845 break;
5111
5112 case EWPNGRAVITY:
5113 if(auto s=checkEWpn(GET_REF(ewpnref)))
5114 ret=((s->moveflags & move_obeys_grav) ? 10000 : 0);
5115
5116 break;
5117
5118 case EWPNSTEP:
5119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 647006 times.
647006 if(auto s=checkEWpn(GET_REF(ewpnref)))
5120 {
5121
3/4
✓ Branch 0 taken 610183 times.
✓ Branch 1 taken 36823 times.
✓ Branch 2 taken 610183 times.
✗ Branch 3 not taken.
647006 if ( get_qr(qr_STEP_IS_FLOAT) || replay_is_active() )
5122 {
5123 647006 ret=s->step.getZLong() * 100;
5124 647006 }
5125 //old, buggy code replication, round two: Go! -Z
5126 //else ret = ( ( ( s->step ) * 100.0 ).getZLong() );
5127 //old, buggy code replication, round FOUR: Go! -Z
5128 else ret = (int32_t)((float)s->step * 1000000.0);
5129 647006 }
5130 //else
5131 //{
5132 //old, buggy code replication, round THREE: Go! -Z
5133 // double tmp = ( s->step.getFloat() ) * 1000000.0;
5134 // ret = int32_t(tmp);
5135 //}
5136 647006 break;
5137
5138 case EWPNANGLE:
5139
1/2
✓ Branch 0 taken 908111 times.
✗ Branch 1 not taken.
908111 if(auto s=checkEWpn(GET_REF(ewpnref)))
5140 908111 ret=(int32_t)(s->angle*10000);
5141
5142 908111 break;
5143
5144 case EWPNDEGANGLE:
5145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3341 times.
3341 if(auto s=checkEWpn(GET_REF(ewpnref)))
5146 {
5147 3341 ret=(int32_t)(s->angle*(180.0 / PI)*10000);
5148 3341 }
5149
5150 3341 break;
5151
5152 case EWPNVX:
5153 if(auto s=checkEWpn(GET_REF(ewpnref)))
5154 {
5155 if (s->angular)
5156 ret = int32_t(zc::math::Cos(s->angle)*10000.0*s->step);
5157 else
5158 {
5159 switch(NORMAL_DIR(s->dir))
5160 {
5161 case l_up:
5162 case l_down:
5163 case left:
5164 ret = int32_t(-10000.0*s->step);
5165 break;
5166 case r_up:
5167 case r_down:
5168 case right:
5169 ret = int32_t(10000.0*s->step);
5170 break;
5171
5172 default:
5173 ret = 0;
5174 break;
5175 }
5176 }
5177 }
5178
5179 break;
5180
5181 case EWPNVY:
5182 if(auto s=checkEWpn(GET_REF(ewpnref)))
5183 {
5184 if (s->angular)
5185 ret = int32_t(zc::math::Sin(s->angle)*10000.0*s->step);
5186 else
5187 {
5188 switch(NORMAL_DIR(s->dir))
5189 {
5190 case l_up:
5191 case r_up:
5192 case up:
5193 ret = int32_t(-10000.0*s->step);
5194 break;
5195 case l_down:
5196 case r_down:
5197 case down:
5198 ret = int32_t(10000.0*s->step);
5199 break;
5200
5201 default:
5202 ret = 0;
5203 break;
5204 }
5205 }
5206 }
5207
5208 break;
5209
5210
5211 case EWPNANGULAR:
5212
1/2
✓ Branch 0 taken 170980 times.
✗ Branch 1 not taken.
170980 if(auto s=checkEWpn(GET_REF(ewpnref)))
5213 170980 ret=s->angular*10000;
5214
5215 170980 break;
5216
5217 case EWPNAUTOROTATE:
5218 if(auto s=checkEWpn(GET_REF(ewpnref)))
5219 ret=s->autorotate*10000;
5220
5221 break;
5222
5223 case EWPNBEHIND:
5224 if(auto s=checkEWpn(GET_REF(ewpnref)))
5225 ret=s->behind*10000;
5226
5227 break;
5228
5229 case EWPNDRAWTYPE:
5230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46359 times.
46359 if(auto s=checkEWpn(GET_REF(ewpnref)))
5231 46359 ret=s->drawstyle*10000;
5232
5233 46359 break;
5234
5235 case EWPNPOWER:
5236
1/2
✓ Branch 0 taken 99454 times.
✗ Branch 1 not taken.
99454 if(auto s=checkEWpn(GET_REF(ewpnref)))
5237 99454 ret=s->power*10000;
5238
5239 99454 break;
5240
5241 case EWPNDEAD:
5242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6052 times.
6052 if(auto s=checkEWpn(GET_REF(ewpnref)))
5243 6052 ret=s->dead*10000;
5244
5245 6052 break;
5246
5247 case EWPNTYPE:
5248
2/2
✓ Branch 0 taken 72689 times.
✓ Branch 1 taken 2900624 times.
2973313 if(auto s=checkEWpn(GET_REF(ewpnref)))
5249 2900624 ret=s->id*10000;
5250
5251 2973313 break;
5252
5253 case EWPNTILE:
5254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 205116 times.
205116 if(auto s=checkEWpn(GET_REF(ewpnref)))
5255 205116 ret=s->tile*10000;
5256
5257 205116 break;
5258
5259 case EWPNSCRIPTTILE:
5260 if(auto s=checkEWpn(GET_REF(ewpnref)))
5261 ret=s->scripttile*10000;
5262
5263 break;
5264
5265 case EWPNSCRIPTFLIP:
5266 if(auto s=checkEWpn(GET_REF(ewpnref)))
5267 ret=s->scriptflip*10000;
5268
5269 break;
5270
5271 case EWPNCSET:
5272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65418 times.
65418 if(auto s=checkEWpn(GET_REF(ewpnref)))
5273 65418 ret=s->cs*10000;
5274
5275 65418 break;
5276
5277 case EWPNFLASHCSET:
5278 if(auto s=checkEWpn(GET_REF(ewpnref)))
5279 ret=(s->o_cset>>4)*10000;
5280
5281 break;
5282
5283 case EWPNFRAMES:
5284
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32642 times.
32642 if(auto s=checkEWpn(GET_REF(ewpnref)))
5285 32642 ret=s->frames*10000;
5286
5287 32642 break;
5288
5289 case EWPNFRAME:
5290 if(auto s=checkEWpn(GET_REF(ewpnref)))
5291 ret=s->aframe*10000;
5292
5293 break;
5294
5295 case EWPNASPEED:
5296
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32642 times.
32642 if(auto s=checkEWpn(GET_REF(ewpnref)))
5297 32642 ret=s->o_speed*10000;
5298
5299 32642 break;
5300
5301 case EWPNFLASH:
5302 if(auto s=checkEWpn(GET_REF(ewpnref)))
5303 ret=s->flash*10000;
5304
5305 break;
5306
5307 case EWPNFLIP:
5308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12006 times.
12006 if(auto s=checkEWpn(GET_REF(ewpnref)))
5309 12006 ret=s->flip*10000;
5310
5311 12006 break;
5312
5313 case EWPNROTATION:
5314
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218 times.
218 if ( get_qr(qr_OLDSPRITEDRAWS) )
5315 {
5316 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'");
5317 break;
5318 }
5319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218 times.
218 if(auto s=checkEWpn(GET_REF(ewpnref)))
5320 218 ret=s->rotation*10000;
5321
5322 218 break;
5323
5324 case EWPNCOUNT:
5325 6662442 ret=Ewpns.Count()*10000;
5326 6662442 break;
5327
5328 case EWPNEXTEND:
5329 if(auto s=checkEWpn(GET_REF(ewpnref)))
5330 ret=s->extend*10000;
5331
5332 break;
5333
5334 case EWPNOTILE:
5335
1/2
✓ Branch 0 taken 10635 times.
✗ Branch 1 not taken.
10635 if(auto s=checkEWpn(GET_REF(ewpnref)))
5336 10635 ret=s->o_tile*10000;
5337
5338 10635 break;
5339
5340 case EWPNOCSET:
5341 if(auto s=checkEWpn(GET_REF(ewpnref)))
5342 ret=(s->o_cset&15)*10000;
5343
5344 break;
5345
5346 case EWPNHXOFS:
5347
1/2
✓ Branch 0 taken 157773 times.
✗ Branch 1 not taken.
157773 if(auto s=checkEWpn(GET_REF(ewpnref)))
5348 157773 ret=(s->hxofs)*10000;
5349
5350 157773 break;
5351
5352 case EWPNHYOFS:
5353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 157773 times.
157773 if(auto s=checkEWpn(GET_REF(ewpnref)))
5354 157773 ret=(s->hyofs)*10000;
5355
5356 157773 break;
5357
5358 case EWPNXOFS:
5359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48464 times.
48464 if(auto s=checkEWpn(GET_REF(ewpnref)))
5360 48464 ret=((int32_t)(s->xofs))*10000;
5361
5362 48464 break;
5363
5364 case EWPNYOFS:
5365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60558 times.
60558 if(auto s=checkEWpn(GET_REF(ewpnref)))
5366
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60558 times.
60558 ret=((int32_t)(s->yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)))*10000;
5367
5368 60558 break;
5369
5370 case EWPNSHADOWXOFS:
5371 if(auto s=checkEWpn(GET_REF(ewpnref)))
5372 ret=((int32_t)(s->shadowxofs))*10000;
5373
5374 break;
5375
5376 case EWPNSHADOWYOFS:
5377 if(auto s=checkEWpn(GET_REF(ewpnref)))
5378 ret=((int32_t)(s->shadowyofs))*10000;
5379
5380 break;
5381 case EWPNTOTALDYOFFS:
5382 if(auto s=checkEWpn(GET_REF(ewpnref)))
5383 ret = ((int32_t)(s->yofs-(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset))
5384 + ((s->switch_hooked && Hero.switchhookstyle == swRISE)
5385 ? -(8-(abs(Hero.switchhookclk-32)/4)) : 0) * 10000);
5386 break;
5387
5388 case EWPNZOFS:
5389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1880 times.
1880 if(auto s=checkEWpn(GET_REF(ewpnref)))
5390 1880 ret=((int32_t)(s->zofs))*10000;
5391
5392 1880 break;
5393
5394 case EWPNHXSZ:
5395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149564 times.
149564 if(auto s=checkEWpn(GET_REF(ewpnref)))
5396 149564 ret=(s->hit_width)*10000;
5397
5398 149564 break;
5399
5400 case EWPNHYSZ:
5401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149564 times.
149564 if(auto s=checkEWpn(GET_REF(ewpnref)))
5402 149564 ret=(s->hit_height)*10000;
5403
5404 149564 break;
5405
5406 case EWPNHZSZ:
5407
1/2
✓ Branch 0 taken 81355 times.
✗ Branch 1 not taken.
81355 if(auto s=checkEWpn(GET_REF(ewpnref)))
5408 81355 ret=(s->hzsz)*10000;
5409
5410 81355 break;
5411
5412 case EWPNTXSZ:
5413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 125257 times.
125257 if(auto s=checkEWpn(GET_REF(ewpnref)))
5414 125257 ret=(s->txsz)*10000;
5415
5416 125257 break;
5417
5418 case EWPNTYSZ:
5419
1/2
✓ Branch 0 taken 125257 times.
✗ Branch 1 not taken.
125257 if(auto s=checkEWpn(GET_REF(ewpnref)))
5420 125257 ret=(s->tysz)*10000;
5421
5422 125257 break;
5423
5424 case EWPNCOLLDET:
5425
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13583 times.
13583 if(auto s=checkEWpn(GET_REF(ewpnref)))
5426 13583 ret=(s->scriptcoldet)*10000;
5427
5428 13583 break;
5429
5430 case EWPNENGINEANIMATE:
5431 if(auto s=checkEWpn(GET_REF(ewpnref)))
5432 ret=(s->do_animation)*10000;
5433
5434 break;
5435
5436 case EWPNPARENT:
5437 if(auto s=checkEWpn(GET_REF(ewpnref)))
5438 ret= ((get_qr(qr_OLDEWPNPARENT)) ? (s->parentid)*10000 : (s->parentid));
5439
5440 break;
5441
5442 case EWEAPONSCRIPTUID:
5443 if(auto s=checkEWpn(GET_REF(ewpnref)))
5444 ret=(s->getUID());
5445
5446 break;
5447
5448 case EWPNPARENTUID:
5449 if(auto s=checkEWpn(GET_REF(ewpnref)))
5450 ret = s->parent ? s->parent->getUID() : 0;
5451
5452 break;
5453
5454 case EWPNSCRIPT:
5455
1/2
✓ Branch 0 taken 7568 times.
✗ Branch 1 not taken.
7568 if(auto s=checkEWpn(GET_REF(ewpnref)))
5456 7568 ret=(s->script)*10000;
5457
5458 7568 break;
5459
5460 case EWPNFALLCLK:
5461 if(auto s=checkEWpn(GET_REF(ewpnref)))
5462 {
5463 ret = s->fallclk * 10000;
5464 }
5465 break;
5466
5467 case EWPNFALLCMB:
5468 if(auto s=checkEWpn(GET_REF(ewpnref)))
5469 {
5470 ret = s->fallCombo * 10000;
5471 }
5472 break;
5473
5474 case EWPNDROWNCLK:
5475 if(auto s=checkEWpn(GET_REF(ewpnref)))
5476 {
5477 ret = s->drownclk * 10000;
5478 }
5479 break;
5480
5481 case EWPNDROWNCMB:
5482 if(auto s=checkEWpn(GET_REF(ewpnref)))
5483 {
5484 ret = s->drownCombo * 10000;
5485 }
5486 break;
5487 case EWPNFAKEZ:
5488 if(auto s=checkEWpn(GET_REF(ewpnref)))
5489 {
5490 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
5491 {
5492 ret=(s->fakez).getZLong();
5493 }
5494 else
5495 ret=((int32_t)s->fakez)*10000;
5496 }
5497 break;
5498
5499 case EWPNGLOWRAD:
5500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30735 times.
30735 if(auto s=checkEWpn(GET_REF(ewpnref)))
5501 {
5502 30735 ret = s->glowRad * 10000;
5503 30735 }
5504 30735 break;
5505
5506 case EWPNGLOWSHP:
5507 if(auto s=checkEWpn(GET_REF(ewpnref)))
5508 {
5509 ret = s->glowShape * 10000;
5510 }
5511 break;
5512
5513 case EWPNUNBL:
5514 if(auto s=checkEWpn(GET_REF(ewpnref)))
5515 {
5516 ret = s->unblockable * 10000;
5517 }
5518 break;
5519
5520 case EWPNSHADOWSPR:
5521 if(auto s=checkEWpn(GET_REF(ewpnref)))
5522 {
5523 ret = s->spr_shadow * 10000;
5524 }
5525 break;
5526 case EWSWHOOKED:
5527 if(auto s=checkEWpn(GET_REF(ewpnref)))
5528 {
5529 ret = s->switch_hooked ? 10000 : 0;
5530 }
5531 break;
5532 case EWPNTIMEOUT:
5533 if(auto s=checkEWpn(GET_REF(ewpnref)))
5534 {
5535 ret = s->weap_timeout * 10000;
5536 }
5537 break;
5538 case EWPNDEATHITEM:
5539 if(auto s=checkEWpn(GET_REF(ewpnref)))
5540 {
5541 ret = s->death_spawnitem * 10000;
5542 }
5543 break;
5544 case EWPNDEATHDROPSET:
5545 if(auto s=checkEWpn(GET_REF(ewpnref)))
5546 {
5547 ret = s->death_spawndropset * 10000;
5548 }
5549 break;
5550 case EWPNDEATHIPICKUP:
5551 if(auto s=checkEWpn(GET_REF(ewpnref)))
5552 {
5553 ret = s->death_item_pflags * 10000;
5554 }
5555 break;
5556 case EWPNDEATHSPRITE:
5557 if(auto s=checkEWpn(GET_REF(ewpnref)))
5558 {
5559 ret = s->death_sprite * 10000;
5560 }
5561 break;
5562 case EWPNDEATHSFX:
5563 if(auto s=checkEWpn(GET_REF(ewpnref)))
5564 {
5565 ret = s->death_sfx * 10000;
5566 }
5567 break;
5568 case EWPNLIFTLEVEL:
5569 if(auto s=checkEWpn(GET_REF(ewpnref)))
5570 {
5571 ret = s->lift_level * 10000;
5572 }
5573 break;
5574 case EWPNLIFTTIME:
5575 if(auto s=checkEWpn(GET_REF(ewpnref)))
5576 {
5577 ret = s->lift_time * 10000;
5578 }
5579 break;
5580 case EWPNLIFTHEIGHT:
5581 if(auto s=checkEWpn(GET_REF(ewpnref)))
5582 {
5583 ret = s->lift_height.getZLong();
5584 }
5585 break;
5586
5587 case SCREENSCRDATASIZE:
5588 {
5589 int index = map_screen_index(cur_map, ri->screenref);
5590 if (index < 0) break;
5591 ret = 10000*game->scriptDataSize(index);
5592 break;
5593 }
5594
5595 case DISTANCE:
5596 {
5597 823233 double x1 = double(GET_D(rSFTEMP) / 10000.0);
5598 823233 double y1 = double(GET_D(rINDEX) / 10000.0);
5599 823233 double x2 = double(GET_D(rINDEX2) / 10000.0);
5600 823233 double y2 = double(GET_D(rEXP1) / 10000.0);
5601
5602
5603
5604 823233 int32_t result = FFCore.Distance(x1, y1, x2, y2);
5605 823233 ret = (result);
5606
5607 823233 break;
5608 }
5609 case LONGDISTANCE:
5610 {
5611 double x1 = double(GET_D(rSFTEMP));
5612 double y1 = double(GET_D(rINDEX));
5613 double x2 = double(GET_D(rINDEX2));
5614 double y2 = double(GET_D(rEXP1));
5615
5616
5617
5618 int32_t result = FFCore.LongDistance(x1, y1, x2, y2);
5619 ret = (result);
5620
5621 break;
5622 }
5623
5624 case DISTANCESCALE:
5625 {
5626 double x1 = (double)(GET_D(rSFTEMP) / 10000.0);
5627 double y1 = (double)(GET_D(rINDEX) / 10000.0);
5628 double x2 = (double)(GET_D(rINDEX2) / 10000.0);
5629 double y2 = (double)(GET_D(rEXP1) / 10000.0);
5630
5631 int32_t scale = (GET_D(rWHAT_NO_7)/10000);
5632
5633 if ( !scale ) scale = 10000;
5634 int32_t result = FFCore.Distance(x1, y1, x2, y2, scale);
5635 ret = (result);
5636
5637 break;
5638 }
5639 case LONGDISTANCESCALE:
5640 {
5641 double x1 = (double)(GET_D(rSFTEMP));
5642 double y1 = (double)(GET_D(rINDEX));
5643 double x2 = (double)(GET_D(rINDEX2));
5644 double y2 = (double)(GET_D(rEXP1));
5645
5646 int32_t scale = (GET_D(rWHAT_NO_7));
5647
5648 if ( !scale ) scale = 1;
5649 int32_t result = FFCore.LongDistance(x1, y1, x2, y2, scale);
5650 ret = (result);
5651
5652 break;
5653 }
5654
5655 case ALLOCATEBITMAPR:
5656 450 ret=FFCore.get_free_bitmap();
5657 450 break;
5658
5659 case GETMIDI:
5660 107342 ret=(currmidi-(ZC_MIDI_COUNT-1))*10000;
5661 107342 break;
5662
5663 case CURDSCR:
5664 {
5665 12771766 int32_t di = (get_currscr()-DMaps[get_currdmap()].xoff);
5666
2/2
✓ Branch 0 taken 5181058 times.
✓ Branch 1 taken 7590708 times.
12771766 ret=(DMaps[get_currdmap()].type==dmOVERW ? cur_screen : di)*10000;
5667 }
5668 12771766 break;
5669
5670 case GAMEMAXMAPS:
5671 96 ret = (map_count)*10000;
5672 96 break;
5673 case GAMENUMMESSAGES:
5674 ret = (msg_count-1) * 10000;
5675 break;
5676
5677 case CURDMAP:
5678 65088848 ret=cur_dmap*10000;
5679 65088848 break;
5680
5681 case CURLEVEL:
5682 16014487 ret=DMaps[get_currdmap()].level*10000;
5683 16014487 break;
5684
5685 case GAMECLICKFREEZE:
5686 ret=disableClickToFreeze?0:10000;
5687 break;
5688
5689
5690 case NOACTIVESUBSC:
5691 ret=Hero.stopSubscreenFalling()?10000:0;
5692 break;///----------------------------------------------------------------------------------------------------//
5693 //BottleTypes
5694
5695 case BOTTLENEXT:
5696 {
5697 if(bottletype* ptr = checkBottleData(GET_REF(bottletyperef)))
5698 {
5699 ret = 10000L * ptr->next_type;
5700 }
5701 else ret = -10000L;
5702 }
5703 break;
5704
5705 ///----------------------------------------------------------------------------------------------------//
5706 //Region
5707
5708 case REGION_WIDTH:
5709 {
5710 390647 ret = world_w * 10000;
5711 }
5712 390647 break;
5713
5714 case REGION_HEIGHT:
5715 {
5716 382914 ret = world_h * 10000;
5717 }
5718 382914 break;
5719
5720 case REGION_SCREEN_WIDTH:
5721 {
5722 2662 ret = cur_region.screen_width * 10000;
5723 }
5724 2662 break;
5725
5726 case REGION_SCREEN_HEIGHT:
5727 {
5728 2599 ret = cur_region.screen_height * 10000;
5729 }
5730 2599 break;
5731
5732 case REGION_NUM_COMBOS:
5733 {
5734 11700413 ret = region_num_rpos * 10000;
5735 }
5736 11700413 break;
5737
5738 case REGION_ID:
5739 {
5740 27276802 ret = get_current_region_id() * 10000;
5741 }
5742 27276802 break;
5743
5744 case REGION_ORIGIN_SCREEN:
5745 {
5746 ret = cur_screen;
5747 }
5748 break;
5749
5750 ///----------------------------------------------------------------------------------------------------//
5751 //Viewport
5752
5753 case VIEWPORT_TARGET:
5754 {
5755 ret = get_viewport_sprite()->uid;
5756 }
5757 break;
5758
5759 case VIEWPORT_MODE:
5760 {
5761 ret = (int)viewport_mode;
5762 }
5763 break;
5764
5765 case VIEWPORT_X:
5766 {
5767 24940 ret = viewport.x * 10000;
5768 }
5769 24940 break;
5770
5771 case VIEWPORT_Y:
5772 {
5773 21112 ret = viewport.y * 10000;
5774 }
5775 21112 break;
5776
5777 case VIEWPORT_WIDTH:
5778 {
5779 8014 ret = viewport.w * 10000;
5780 }
5781 8014 break;
5782
5783 case VIEWPORT_HEIGHT:
5784 {
5785 11842 ret = viewport.h * 10000;
5786 }
5787 11842 break;
5788
5789 ///----------------------------------------------------------------------------------------------------//
5790 //Screen Information
5791
5792 #define GET_SCREENDATA_VAR_INT32(member) \
5793 { \
5794 ret = (get_scr(GET_REF(screenref))->member *10000); \
5795 } \
5796
5797 #define GET_SCREENDATA_VAR_INT16(member) \
5798 { \
5799 ret = (get_scr(GET_REF(screenref))->member *10000); \
5800 } \
5801
5802 #define GET_SCREENDATA_VAR_BYTE(member) \
5803 { \
5804 ret = (get_scr(GET_REF(screenref))->member *10000); \
5805 } \
5806
5807 #define GET_SCREENDATA_BYTE_INDEX(member, indexbound) \
5808 { \
5809 int32_t indx = GET_D(rINDEX) / 10000; \
5810 ret = (get_scr(GET_REF(screenref))->member[indx] *10000); \
5811 } \
5812
5813 //byte
5814 #define GET_SCREENDATA_LAYER_INDEX(member, indexbound) \
5815 { \
5816 int32_t indx = GET_D(rINDEX) / 10000; \
5817 if (BC::checkIndex(indx, 1, indexbound) != SH::_NoError) \
5818 { \
5819 ret = -10000; \
5820 } \
5821 else \
5822 { \
5823 ret = (get_scr(GET_REF(screenref))->member[indx-1] *10000); \
5824 } \
5825 } \
5826
5827 #define GET_SCREENDATA_BOOL_INDEX(member, indexbound) \
5828 { \
5829 int32_t indx = GET_D(rINDEX) / 10000; \
5830 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
5831 { \
5832 ret = -10000; \
5833 } \
5834 else \
5835 { \
5836 ret = (get_scr(GET_REF(screenref))->member[indx]?10000:0); \
5837 } \
5838 } \
5839
5840
5841 #define GET_SCREENDATA_FLAG(member, str, indexbound) \
5842 { \
5843 int32_t flag = (value/10000); \
5844 ret = (get_scr(GET_REF(screenref))->member&flag) ? 10000 : 0); \
5845 } \
5846
5847 case SCREENDATAVALID: GET_SCREENDATA_VAR_BYTE(valid); break; //b
5848 case SCREENDATAGUY: GET_SCREENDATA_VAR_BYTE(guy); break; //b
5849 case SCREENDATASTRING: GET_SCREENDATA_VAR_INT32(str); break; //w
5850 case SCREENDATAROOM: GET_SCREENDATA_VAR_BYTE(room); break; //b
5851 case SCREENDATAITEM:
5852 {
5853 mapscr* scr = get_scr(GET_REF(screenref));
5854 if(scr->hasitem)
5855 ret = (scr->item *10000);
5856 else ret = -10000;
5857 break;
5858 }
5859 case SCREENDATAHASITEM: GET_SCREENDATA_VAR_BYTE(hasitem); break; //b
5860 case SCREENDATADOORCOMBOSET: GET_SCREENDATA_VAR_INT32(door_combo_set); break; //w
5861 case SCREENDATAWARPRETURNC: GET_SCREENDATA_VAR_INT32(warpreturnc); break; //w
5862 case SCREENDATASTAIRX: GET_SCREENDATA_VAR_BYTE(stairx); break; //b
5863 case SCREENDATASTAIRY: GET_SCREENDATA_VAR_BYTE(stairy); break; //b
5864 case SCREENDATAITEMX: GET_SCREENDATA_VAR_BYTE(itemx); break; //itemx
5865 case SCREENDATAITEMY: GET_SCREENDATA_VAR_BYTE(itemy); break; //itemy
5866 170974 case SCREENDATACOLOUR: GET_SCREENDATA_VAR_INT32(color); break; //w
5867 case SCREENDATAENEMYFLAGS: GET_SCREENDATA_VAR_BYTE(flags11); break; //b
5868 // Note: never used?
5869 case SCREENDATADOOR: GET_SCREENDATA_BYTE_INDEX(door, 3); break; //b, 4 of these
5870 case SCREENDATAEXITDIR: GET_SCREENDATA_VAR_BYTE(exitdir); break; //b
5871 case SCREENDATAPATTERN: GET_SCREENDATA_VAR_BYTE(pattern); break; //b
5872 case SCREENDATAWARPARRIVALX: GET_SCREENDATA_VAR_BYTE(warparrivalx); break; //b
5873 case SCREENDATAWARPARRIVALY: GET_SCREENDATA_VAR_BYTE(warparrivaly); break; //b
5874 case SCREENDATASIDEWARPINDEX: GET_SCREENDATA_VAR_BYTE(sidewarpindex); break; //b
5875 case SCREENDATACATCHALL: GET_SCREENDATA_VAR_INT32(catchall); break; //W
5876
5877 case SCREENDATACSENSITIVE: GET_SCREENDATA_VAR_BYTE(csensitive); break; //B
5878 case SCREENDATANORESET: GET_SCREENDATA_VAR_INT32(noreset); break; //W
5879 case SCREENDATANOCARRY: GET_SCREENDATA_VAR_INT32(nocarry); break; //W
5880 case SCREENDATATIMEDWARPTICS: GET_SCREENDATA_VAR_INT32(timedwarptics); break; //W
5881 case SCREENDATANEXTMAP: GET_SCREENDATA_VAR_BYTE(nextmap); break; //B
5882 case SCREENDATANEXTSCREEN: GET_SCREENDATA_VAR_BYTE(nextscr); break; //B
5883 case SCREENDATAVIEWX: break;//GET_SCREENDATA_VAR_INT32(viewX, "ViewX"); break; //W
5884 case SCREENDATAVIEWY: break;//GET_SCREENDATA_VAR_INT32(viewY, "ViewY"); break; //W
5885 case SCREENDATASCREENWIDTH: break;//GET_SCREENDATA_VAR_BYTE(scrWidth, "Width"); break; //B
5886 case SCREENDATASCREENHEIGHT: break;//GET_SCREENDATA_VAR_BYTE(scrHeight, "Height"); break; //B
5887 case SCREENDATAENTRYX: GET_SCREENDATA_VAR_BYTE(entry_x); break; //B
5888 case SCREENDATAENTRYY: GET_SCREENDATA_VAR_BYTE(entry_y); break; //B
5889 //Number of ffcs that are in use (have valid data
5890 // Note: that is totally not what its doing.
5891 case SCREENDATANUMFF:
5892 {
5893 int id = GET_D(rINDEX) / 10000;
5894 if (auto ffc = ResolveFFCWithID(id))
5895 ret = ffc->data != 0 ? 10000 : 0;
5896 break;
5897 }
5898
5899 // Note: never used?
5900 case SCREENDATAFFINITIALISED: {
5901 int32_t indx = GET_D(rINDEX) / 10000;
5902 if (indx < 0 || indx > MAX_FFCID)
5903 {
5904 scripting_log_error_with_context("Invalid index: %d", (indx));
5905 ret = -10000;
5906 }
5907 else
5908 {
5909 ret = get_script_engine_data(ScriptType::FFC, indx).initialized ? 10000 : 0;
5910 }
5911 }
5912 break;
5913
5914 case SCREENDATASCRIPTENTRY:
5915 {
5916 Z_scripterrlog("Unimplemented: %s\n", "ScriptEntry");
5917 ret = -10000;
5918 }
5919 break;
5920 case SCREENDATASCRIPTOCCUPANCY:
5921 {
5922 Z_scripterrlog("Unimplemented: %s\n", "ScriptOccupancy");
5923 ret = -10000;
5924 }
5925 break;
5926 case SCREENDATASCRIPTEXIT:
5927 {
5928 Z_scripterrlog("Unimplemented: %s\n", "ExitScript");
5929 ret = -10000;
5930 }
5931 break;
5932
5933 case SCREENDATAOCEANSFX: GET_SCREENDATA_VAR_BYTE(oceansfx); break; //B
5934 case SCREENDATABOSSSFX: GET_SCREENDATA_VAR_BYTE(bosssfx); break; //B
5935 17 case SCREENDATASECRETSFX: GET_SCREENDATA_VAR_BYTE(secretsfx); break; //B
5936 case SCREENDATAHOLDUPSFX: GET_SCREENDATA_VAR_BYTE(holdupsfx); break; //B
5937 case SCREENDATASCREENMIDI:
5938 {
5939 ret = ((get_scr(GET_REF(screenref))->screen_midi+(MIDIOFFSET_MAPSCR-MIDIOFFSET_ZSCRIPT)) *10000);
5940 break;
5941 }
5942 case SCREENDATA_GRAVITY_STRENGTH:
5943 {
5944 ret = get_scr(GET_REF(screenref))->screen_gravity.getZLong();
5945 break;
5946 }
5947 case SCREENDATA_TERMINAL_VELOCITY:
5948 {
5949 ret = get_scr(GET_REF(screenref))->screen_terminal_v.getZLong();
5950 break;
5951 }
5952 case SCREENDATALENSLAYER: GET_SCREENDATA_VAR_BYTE(lens_layer); break; //B, OLD QUESTS ONLY?
5953
5954 case SCREENSECRETSTRIGGERED:
5955 {
5956 41995 ret = get_screen_state(GET_REF(screenref)).triggered_secrets ? 10000L : 0L;
5957 41995 break;
5958 }
5959
5960 case SCREENDATAGUYCOUNT:
5961 {
5962 int mi = mapind(cur_map, GET_REF(screenref));
5963 if(mi < 0)
5964 ret = -10000;
5965 else ret = game->guys[mi] * 10000;
5966 break;
5967 }
5968 case SCREENDATAEXDOOR:
5969 {
5970 ret = 0;
5971 int mi = mapind(cur_map, GET_REF(screenref));
5972 if(mi < 0) break;
5973 int dir = SH::read_stack(ri->sp+1) / 10000;
5974 int ind = SH::read_stack(ri->sp+0) / 10000;
5975 if(unsigned(dir) > 3)
5976 Z_scripterrlog("Invalid dir '%d' passed to 'Screen->GetExDoor()'; must be 0-3\n", dir);
5977 else if(unsigned(ind) > 7)
5978 Z_scripterrlog("Invalid index '%d' passed to 'Screen->GetExDoor()'; must be 0-7\n", ind);
5979 else
5980 {
5981 int bit = 1<<ind;
5982 ret = (game->xdoors[mi][dir]&bit) ? 10000 : 0;
5983 }
5984 break;
5985 }
5986
5987 case SHOWNMSG:
5988 {
5989
4/4
✓ Branch 0 taken 3052 times.
✓ Branch 1 taken 10916 times.
✓ Branch 2 taken 3000 times.
✓ Branch 3 taken 52 times.
13968 ret = ((msg_active || msg_onscreen) ? msgstr : 0) * 10000L;
5990 13968 break;
5991 }
5992
5993 case SDDD:
5994 43250 ret=FFScript::get_screen_d((GET_D(rINDEX))/10000 + ((get_currdmap())<<7), GET_D(rINDEX2) / 10000);
5995 43250 break;
5996
5997 case LINKOTILE:
5998 ret=FFCore.getHeroOTile(GET_D(rINDEX)/10000, GET_D(rINDEX2) / 10000);
5999 break;
6000
6001 case SDDDD:
6002 280 ret=FFScript::get_screen_d(GET_D(rINDEX2) / 10000 + ((GET_D(rINDEX)/10000)<<7), GET_D(rEXP1) / 10000);
6003 280 break;
6004
6005 case SCREENSCRIPT:
6006 ret=get_scr(GET_REF(screenref))->script*10000;
6007 break;
6008
6009 //These use the same method as GetScreenD -Z
6010 case SCREENWIDTH:
6011 // ret=FFScript::get_screenWidth(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)]);
6012 break;
6013
6014 case SCREENHEIGHT:
6015 // ret=FFScript::get_screenHeight(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)]);
6016 break;
6017
6018 case SCREENVIEWX:
6019 // ret=get_screenViewX(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)]);
6020 break;
6021
6022 case SCREENVIEWY:
6023 // ret=get_screenViewY(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)]);
6024 break;
6025
6026 case LIT:
6027 10246 ret= get_lights() ? 10000 : 0;
6028 10246 break;
6029
6030 case WAVY:
6031 7214 ret = wavy*10000;
6032 7214 break;
6033
6034 case QUAKE:
6035 2391 ret = quakeclk*10000;
6036 2391 break;
6037
6038 case NPCCOUNT:
6039 30000057 ret = guys.Count()*10000;
6040 30000057 break;
6041
6042 case ROOMDATA:
6043 47 ret = get_scr(GET_REF(screenref))->catchall*10000;
6044 47 break;
6045
6046 case ROOMTYPE:
6047 2 ret = get_scr(GET_REF(screenref))->room*10000;
6048 2 break;
6049
6050 case PUSHBLOCKX:
6051
2/2
✓ Branch 0 taken 38077 times.
✓ Branch 1 taken 710696 times.
748773 ret = mblock2.active() ? int32_t(mblock2.x)*10000 : -10000;
6052 748773 break;
6053
6054 case PUSHBLOCKY:
6055
2/2
✓ Branch 0 taken 14477 times.
✓ Branch 1 taken 98007 times.
112484 ret = mblock2.active() ? int32_t(mblock2.y)*10000 : -10000;
6056 112484 break;
6057
6058 case PUSHBLOCKLAYER:
6059 ret = mblock2.active() ? int32_t(mblock2.blockLayer)*10000 : -10000;
6060 break;
6061
6062 case PUSHBLOCKCOMBO:
6063 ret = mblock2.bcombo*10000;
6064 break;
6065
6066 case PUSHBLOCKCSET:
6067 ret = mblock2.cs*10000;
6068 break;
6069
6070 case UNDERCOMBO:
6071 1634 ret = get_scr(GET_REF(screenref))->undercombo*10000;
6072 1634 break;
6073
6074 case UNDERCSET:
6075 1608 ret = get_scr(GET_REF(screenref))->undercset*10000;
6076 1608 break;
6077
6078 case SCREEN_INDEX:
6079 32 ret = ri->screenref*10000;
6080 32 break;
6081
6082 case SCREEN_DRAW_ORIGIN:
6083 ret = (int)ri->screen_draw_origin;
6084 break;
6085
6086 case SCREEN_DRAW_ORIGIN_TARGET:
6087 ret = ri->screen_draw_origin_target;
6088 break;
6089
6090 //Creates an lweapon using an iemdata struct values to generate its properties.
6091 //Useful in conjunction with the new weapon editor.
6092 case CREATELWPNDX:
6093 {
6094 //Z_message("Trying to get Hero->SetExtend().\n");
6095 int32_t ID = (GET_D(rINDEX) / 10000);
6096 int32_t itemid = (GET_D(rINDEX2)/10000);
6097 itemid = vbound(itemid,0,(MAXITEMS-1));
6098
6099 // TODO: use has_space()
6100 if ( Lwpns.Count() < 256 )
6101 {
6102
6103 (void)Lwpns.add
6104 (
6105 new weapon
6106 (
6107 (zfix)0, /*X*/
6108 (zfix)0, /*Y*/
6109 (zfix)0, /*Z*/
6110 ID, /*id*/
6111 0, /*type*/
6112 0, /*power*/
6113 0, /*dir*/
6114 -1, /*Parentid*/
6115 Hero.getUID(), /*prntid*/
6116 false, /*isdummy*/
6117 1, /*script_gen*/
6118 1, /*islwpn*/
6119 (ID==wWind?1:0) /*special*/
6120 )
6121 );
6122 ri->lwpnref = Lwpns.spr(Lwpns.Count() - 1)->getUID();
6123
6124 weapon *w = (weapon*)Lwpns.spr(Lwpns.Count()-1); //last created
6125 //w->LOADGFX(FFCore.getDefWeaponSprite(ID)); //What the fuck Zoria, this broke old quests...
6126 w->ScriptGenerated = 1;
6127 w->isLWeapon = 1;
6128 if(ID == wWind) w->specialinfo = 1;
6129 //weapon *w = (weapon*)Lwpns.spr(Lwpns.Count()-1); //last created
6130 //w->LOADGFX(FFCore.getDefWeaponSprite(ID)); //not needed here because this has access to wpn->prent
6131 }
6132 else
6133 {
6134 Z_scripterrlog("Tried to create too many LWeapons on the screen. The current LWeapon count is: %d\n", Lwpns.Count());
6135 ri->lwpnref = 0;
6136 }
6137
6138 ret = ri->lwpnref;
6139 }
6140 break;
6141
6142 ///----------------------------------------------------------------------------------------------------//
6143 //New Datatype Variables
6144
6145 ///----------------------------------------------------------------------------------------------------//
6146 //spritedata sp-> Variables
6147
6148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5603 times.
5603 case SPRITEDATATILE: GET_SPRITEDATA_VAR_INT(tile) break;
6149 case SPRITEDATAMISC: GET_SPRITEDATA_VAR_INT(misc) break;
6150 case SPRITEDATACSETS:
6151 {
6152
1/2
✓ Branch 0 taken 5603 times.
✗ Branch 1 not taken.
5603 if (auto sd = checkSpriteData(GET_REF(spritedataref)); !sd)
6153 ret = -10000;
6154 else
6155 5603 ret = ((sd->csets & 0xF) * 10000);
6156 5603 break;
6157 }
6158 case SPRITEDATAFLCSET:
6159 {
6160 if (auto sd = checkSpriteData(GET_REF(spritedataref)); !sd)
6161 ret = -10000;
6162 else
6163 ret = (((sd->csets & 0xF0)>>4) * 10000);
6164 break;
6165 }
6166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5603 times.
5603 case SPRITEDATAFRAMES: GET_SPRITEDATA_VAR_INT(frames) break;
6167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5603 times.
5603 case SPRITEDATASPEED: GET_SPRITEDATA_VAR_INT(speed) break;
6168 case SPRITEDATATYPE: GET_SPRITEDATA_VAR_INT(type) break;
6169 case SPRITEDATAID:
6170 {
6171 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) )
6172 {
6173 ret = -10000;
6174 Z_scripterrlog("Invalid Sprite ID passed to spritedata->ID: %d\n", GET_REF(spritedataref));
6175 break;
6176 }
6177 ret = ri->spritedataref*10000;
6178 break;
6179 }
6180
6181 ///----------------------------------------------------------------------------------------------------//
6182 //mapdata m-> variables
6183 #define GET_MAPDATA_VAR_INT32(member) \
6184 { \
6185 if ( mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)) ) \
6186 { \
6187 ret = (m->member *10000); \
6188 } \
6189 else \
6190 { \
6191 ret = -10000; \
6192 } \
6193 } \
6194
6195 #define GET_MAPDATA_VAR_INT16(member) \
6196 { \
6197 if ( mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)) ) \
6198 { \
6199 ret = (m->member *10000); \
6200 } \
6201 else \
6202 { \
6203 ret = -10000; \
6204 } \
6205 } \
6206
6207 #define GET_MAPDATA_VAR_BYTE(member) \
6208 { \
6209 if ( mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)) ) \
6210 { \
6211 ret = (m->member *10000); \
6212 } \
6213 else \
6214 { \
6215 ret = -10000; \
6216 } \
6217 } \
6218
6219 #define GET_MAPDATA_FLAG(member) \
6220 { \
6221 int32_t flag = (value/10000); \
6222 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
6223 { \
6224 ret = (m->member&flag) ? 10000 : 0); \
6225 } \
6226 else \
6227 { \
6228 ret = -10000; \
6229 } \
6230 } \
6231
6232 #define GET_MAPDATA_FFCPOS_INDEX32(member, indexbound) \
6233 { \
6234 int32_t index = (GET_D(rINDEX) / 10000); \
6235 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index)) \
6236 { \
6237 ret = (handle.ffc->member).getZLong(); \
6238 } \
6239 else \
6240 { \
6241 ret = -10000; \
6242 } \
6243 } \
6244
6245 #define GET_MAPDATA_FFC_INDEX32(member, indexbound) \
6246 { \
6247 int32_t index = (GET_D(rINDEX) / 10000); \
6248 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index)) \
6249 { \
6250 ret = (handle.ffc->member)*10000; \
6251 } \
6252 else \
6253 { \
6254 ret = -10000; \
6255 } \
6256 } \
6257
6258 #define GET_MAPDATA_FFC_INDEX32(member, indexbound) \
6259 { \
6260 int32_t index = (GET_D(rINDEX) / 10000); \
6261 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index)) \
6262 { \
6263 ret = (handle.ffc->member)*10000; \
6264 } \
6265 else \
6266 { \
6267 ret = -10000; \
6268 } \
6269 } \
6270
6271 case LOADMAPDATA:
6272 7237302 ret=FFScript::loadMapData();
6273 7237302 break;
6274
6275 case CREATEBITMAP:
6276 {
6277 1509495 ret=FFCore.do_create_bitmap();
6278 1509495 break;
6279 }
6280
6281
1/2
✓ Branch 0 taken 51072 times.
✗ Branch 1 not taken.
51072 case MAPDATAVALID: GET_MAPDATA_VAR_BYTE(valid); break; //b
6282 case MAPDATAGUY: GET_MAPDATA_VAR_BYTE(guy); break; //b
6283 case MAPDATASTRING: GET_MAPDATA_VAR_INT32(str); break; //w
6284 case MAPDATAROOM: GET_MAPDATA_VAR_BYTE(room); break; //b
6285 case MAPDATAITEM:
6286 {
6287 if ( mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)) )
6288 {
6289 if(m->hasitem)
6290 ret = (m->item *10000);
6291 else ret = -10000;
6292 }
6293 else
6294 {
6295 ret = -10000;
6296 }
6297 break;
6298 }
6299 case MAPDATAREGIONID:
6300 {
6301 if (auto scr = ResolveMapdataScr(GET_REF(mapdataref)))
6302 ret = get_region_id(scr->map, scr->screen) * 10000;
6303 break;
6304 }
6305 case MAPDATAHASITEM: GET_MAPDATA_VAR_BYTE(hasitem); break; //b
6306 case MAPDATADOORCOMBOSET: GET_MAPDATA_VAR_INT32(door_combo_set); break; //w
6307 case MAPDATAWARPRETURNC: GET_MAPDATA_VAR_INT32(warpreturnc); break; //w
6308 case MAPDATASTAIRX: GET_MAPDATA_VAR_BYTE(stairx); break; //b
6309 case MAPDATASTAIRY: GET_MAPDATA_VAR_BYTE(stairy); break; //b
6310 case MAPDATAITEMX: GET_MAPDATA_VAR_BYTE(itemx); break; //itemx
6311 case MAPDATAITEMY: GET_MAPDATA_VAR_BYTE(itemy); break; //itemy
6312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51072 times.
51072 case MAPDATACOLOUR: GET_MAPDATA_VAR_INT32(color); break; //w
6313 case MAPDATAENEMYFLAGS: GET_MAPDATA_VAR_BYTE(flags11); break; //b
6314 case MAPDATAEXITDIR: GET_MAPDATA_VAR_BYTE(exitdir); break; //b
6315 case MAPDATAPATTERN: GET_MAPDATA_VAR_BYTE(pattern); break; //b
6316 case MAPDATAWARPARRIVALX: GET_MAPDATA_VAR_BYTE(warparrivalx); break; //b
6317 case MAPDATAWARPARRIVALY: GET_MAPDATA_VAR_BYTE(warparrivaly); break; //b
6318 case MAPDATASIDEWARPINDEX: GET_MAPDATA_VAR_BYTE(sidewarpindex); break; //b
6319 case MAPDATAUNDERCOMBO: GET_MAPDATA_VAR_INT32(undercombo); break; //w
6320 case MAPDATAUNDERCSET: GET_MAPDATA_VAR_BYTE(undercset); break; //b
6321 case MAPDATACATCHALL: GET_MAPDATA_VAR_INT32(catchall); break; //W
6322
6323 case MAPDATACSENSITIVE: GET_MAPDATA_VAR_BYTE(csensitive); break; //B
6324 case MAPDATANORESET: GET_MAPDATA_VAR_INT32(noreset); break; //W
6325 case MAPDATANOCARRY: GET_MAPDATA_VAR_INT32(nocarry); break; //W
6326 case MAPDATATIMEDWARPTICS: GET_MAPDATA_VAR_INT32(timedwarptics); break; //W
6327 case MAPDATANEXTMAP: GET_MAPDATA_VAR_BYTE(nextmap); break; //B
6328 case MAPDATANEXTSCREEN: GET_MAPDATA_VAR_BYTE(nextscr); break; //B
6329
6330 case MAPDATAVIEWX: break;//GET_MAPDATA_VAR_INT32(viewX, "ViewX"); break; //W
6331 case MAPDATASCRIPT: GET_MAPDATA_VAR_INT32(script); break; //W
6332 case MAPDATAVIEWY: break;//GET_MAPDATA_VAR_INT32(viewY, "ViewY"); break; //W
6333 case MAPDATASCREENWIDTH: break;//GET_MAPDATA_VAR_BYTE(scrWidth, "Width"); break; //B
6334 case MAPDATASCREENHEIGHT: break;//GET_MAPDATA_VAR_BYTE(scrHeight, "Height"); break; //B
6335 case MAPDATAENTRYX: GET_MAPDATA_VAR_BYTE(entry_x); break; //B
6336 case MAPDATAENTRYY: GET_MAPDATA_VAR_BYTE(entry_y); break; //B
6337
6338 //Number of ffcs that are in use (have valid data
6339 // NOTE: defunct. Never implemented correctly.
6340 case MAPDATANUMFF:
6341 {
6342 32 int index = GET_D(rINDEX) / 10000;
6343
6344
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index))
6345 {
6346 32 ret = (handle.data() != 0) ? 10000 : 0;
6347 32 }
6348 else
6349 {
6350 ret = 0;
6351 }
6352 32 break;
6353 }
6354
6355 case MAPDATAINTID: //Same form as SetScreenD()
6356 //SetFFCInitD(ffindex, d, value)
6357 {
6358 2004 int32_t index = (GET_D(rINDEX)/10000);
6359 2004 int32_t d_index = GET_D(rINDEX2)/10000;
6360
6361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2004 times.
2004 if (BC::checkBounds(d_index, 0, 7) != SH::_NoError)
6362 break;
6363
6364
1/2
✓ Branch 0 taken 2004 times.
✗ Branch 1 not taken.
2004 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index))
6365 2004 ret = handle.ffc->initd[d_index];
6366 else
6367 {
6368 ret = -10000;
6369 }
6370 2004 break;
6371 }
6372
6373 case MAPDATASCRIPTENTRY:
6374 {
6375 Z_scripterrlog("Unimplemented: %s\n", "ScriptEntry");
6376 ret = -10000;
6377 }
6378 break;
6379 case MAPDATASCRIPTOCCUPANCY:
6380 {
6381 Z_scripterrlog("Unimplemented: %s\n", "ScriptOccupancy");
6382 ret = -10000;
6383 }
6384 break;
6385 case MAPDATASCRIPTEXIT:
6386 {
6387 Z_scripterrlog("Unimplemented: %s\n", "ExitScript");
6388 ret = -10000;
6389 }
6390 break;
6391
6392 case MAPDATAOCEANSFX: GET_MAPDATA_VAR_BYTE(oceansfx); break; //B
6393 case MAPDATABOSSSFX: GET_MAPDATA_VAR_BYTE(bosssfx); break; //B
6394 case MAPDATASECRETSFX: GET_MAPDATA_VAR_BYTE(secretsfx); break; //B
6395 case MAPDATAHOLDUPSFX: GET_MAPDATA_VAR_BYTE(holdupsfx); break; //B
6396 case MAPDATASCREENMIDI:
6397 {
6398 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6399 {
6400 ret = ((m->screen_midi+(MIDIOFFSET_MAPSCR-MIDIOFFSET_ZSCRIPT)) *10000);
6401 }
6402 else
6403 {
6404 ret = -10000;
6405 }
6406 break;
6407 }
6408 case MAPDATA_GRAVITY_STRENGTH:
6409 {
6410 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6411 {
6412 ret = m->screen_gravity.getZLong();
6413 }
6414 else ret = -10000;
6415 break;
6416 }
6417 case MAPDATA_TERMINAL_VELOCITY:
6418 {
6419 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6420 {
6421 ret = m->screen_terminal_v.getZLong();
6422 }
6423 else ret = -10000;
6424 break;
6425 }
6426 case MAPDATALENSLAYER: GET_MAPDATA_VAR_BYTE(lens_layer); break; //B, OLD QUESTS ONLY?
6427 case MAPDATAMAP:
6428 {
6429
1/2
✓ Branch 0 taken 151527 times.
✗ Branch 1 not taken.
151527 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6430 {
6431 151527 ret = getMap(GET_REF(mapdataref)) * 10000;
6432 151527 }
6433 else
6434 {
6435 ret = -10000;
6436 }
6437 151527 break;
6438 }
6439 case MAPDATASCREEN:
6440 {
6441
1/2
✓ Branch 0 taken 314379 times.
✗ Branch 1 not taken.
314379 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6442 {
6443 314379 ret = getScreen(GET_REF(mapdataref)) * 10000;
6444 314379 }
6445 else
6446 {
6447 ret = -10000;
6448 }
6449 314379 break;
6450 }
6451 case MAPDATASCRDATASIZE:
6452 {
6453 ret = -10000;
6454 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6455 {
6456 int index = get_ref_map_index(GET_REF(mapdataref));
6457 if (index < 0) break;
6458
6459 ret = 10000*game->scriptDataSize(index);
6460 }
6461 break;
6462 }
6463 case MAPDATAGUYCOUNT:
6464 {
6465 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6466 {
6467 int mi = get_mi(GET_REF(mapdataref));
6468 if(mi > -1)
6469 {
6470 ret = game->guys[mi] * 10000;
6471 break;
6472 }
6473 }
6474 ret = -10000;
6475 break;
6476 }
6477 case MAPDATAEXDOOR:
6478 {
6479 ret = 0;
6480 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
6481 {
6482 int mi = get_mi(GET_REF(mapdataref));
6483 if(mi < 0) break;
6484 int dir = SH::read_stack(ri->sp+1) / 10000;
6485 int ind = SH::read_stack(ri->sp+0) / 10000;
6486 if(unsigned(dir) > 3)
6487 Z_scripterrlog("Invalid dir '%d' passed to 'mapdata->GetExDoor()'; must be 0-3\n", dir);
6488 else if(unsigned(ind) > 7)
6489 Z_scripterrlog("Invalid index '%d' passed to 'mapdata->GetExDoor()'; must be 0-7\n", ind);
6490 else
6491 {
6492 int bit = 1<<ind;
6493 ret = (game->xdoors[mi][dir]&bit) ? 10000 : 0;
6494 }
6495 }
6496 break;
6497 }
6498
6499 ///----------------------------------------------------------------------------------------------------//
6500 //shopdata sd-> variables
6501
6502 case SHOPDATATYPE:
6503 {
6504 int32_t ref = ri->shopdataref;
6505 if ( ref > NUMINFOSHOPS || ref < 0 ) ret = 0;
6506 else ret = ( ( ref <= NUMSHOPS ) ? 10000 : 20000 );
6507 break;
6508 }
6509
6510 ///----------------------------------------------------------------------------------------------------//
6511 //dmapdata dmd-> variables
6512
6513 //getter
6514 1402 case DMAPDATAID: ret = ri->dmapdataref*10000; break; //read-only, equal to CurrentDMap
6515
6516 case DMAPDATAMAP: //byte
6517 {
6518 193590 ret = ((byte)DMaps[GET_REF(dmapdataref)].map + 1) * 10000; break;
6519 }
6520 case DMAPDATALEVEL: //word
6521 {
6522 ret = ((word)DMaps[GET_REF(dmapdataref)].level) * 10000; break;
6523 }
6524 case DMAPDATAFLOOR: //byte
6525 {
6526 ret = ((byte)DMaps[GET_REF(dmapdataref)].floor) * 10000; break;
6527 }
6528 case DMAPDATAOFFSET: //char
6529 {
6530 8824 ret = ((char)DMaps[GET_REF(dmapdataref)].xoff) * 10000; break;
6531 }
6532 case DMAPDATACOMPASS: //byte
6533 {
6534 128960 ret = ((byte)DMaps[GET_REF(dmapdataref)].compass) * 10000; break;
6535 }
6536 case DMAPDATAPALETTE: //word
6537 {
6538 51092 ret = ((word)DMaps[GET_REF(dmapdataref)].color) * 10000; break;
6539 }
6540 case DMAPSCRIPT: //word
6541 {
6542 814 ret = (DMaps[GET_REF(dmapdataref)].script) * 10000; break;
6543 }
6544 case DMAPDATAMIDI: //byte
6545 {
6546 ret = (DMaps[GET_REF(dmapdataref)].midi-MIDIOFFSET_DMAP) * 10000; break;
6547 }
6548 case DMAPDATA_GRAVITY_STRENGTH:
6549 {
6550 ret = DMaps[GET_REF(dmapdataref)].dmap_gravity.getZLong();
6551 break;
6552 }
6553 case DMAPDATA_TERMINAL_VELOCITY:
6554 {
6555 ret = DMaps[GET_REF(dmapdataref)].dmap_terminal_v.getZLong();
6556 break;
6557 }
6558 case DMAPDATACONTINUE: //byte
6559 {
6560 ret = ((byte)DMaps[GET_REF(dmapdataref)].cont) * 10000; break;
6561 }
6562 case DMAPDATATYPE: //byte
6563 {
6564 13125 ret = ((byte)DMaps[GET_REF(dmapdataref)].type&dmfTYPE) * 10000; break;
6565 }
6566 case DMAPDATASIDEVIEW: //byte
6567 {
6568 1192906 ret = ((DMaps[GET_REF(dmapdataref)].sideview) ? 10000 : 0); break;
6569 }
6570 case DMAPDATAMUISCTRACK: //byte
6571 {
6572 ret = ((byte)DMaps[GET_REF(dmapdataref)].tmusictrack) * 10000; break;
6573 }
6574 case DMAPDATASUBSCRA:
6575 {
6576 ret = ((byte)DMaps[GET_REF(dmapdataref)].active_subscreen) * 10000; break;
6577 }
6578 case DMAPDATASUBSCRP:
6579 {
6580 5120 ret = ((byte)DMaps[GET_REF(dmapdataref)].passive_subscreen) * 10000; break;
6581 }
6582 case DMAPDATASUBSCRO:
6583 {
6584 ret = ((byte)DMaps[GET_REF(dmapdataref)].overlay_subscreen) * 10000; break;
6585 }
6586 case DMAPDATAFLAGS: //int32_t
6587 {
6588 ret = (DMaps[GET_REF(dmapdataref)].flags) * 10000; break;
6589 }
6590 case DMAPDATAMIRRDMAP:
6591 {
6592 ret = (DMaps[GET_REF(dmapdataref)].mirrorDMap) * 10000; break;
6593 }
6594 case DMAPDATALOOPSTART:
6595 {
6596 ret = (DMaps[GET_REF(dmapdataref)].tmusic_loop_start); break;
6597 }
6598 case DMAPDATALOOPEND:
6599 {
6600 ret = (DMaps[GET_REF(dmapdataref)].tmusic_loop_end); break;
6601 }
6602 case DMAPDATAXFADEIN:
6603 {
6604 ret = (DMaps[GET_REF(dmapdataref)].tmusic_xfade_in * 10000); break;
6605 }
6606 case DMAPDATAXFADEOUT:
6607 {
6608 ret = (DMaps[GET_REF(dmapdataref)].tmusic_xfade_out * 10000); break;
6609 }
6610 case DMAPDATAINTROSTRINGID:
6611 {
6612 ret = (DMaps[GET_REF(dmapdataref)].intro_string_id * 10000); break;
6613 }
6614 case MUSICUPDATECOND:
6615 {
6616 ret = ((byte)FFCore.music_update_cond) * 10000; break;
6617 }
6618 case DMAPDATAASUBSCRIPT: //word
6619 {
6620 23552 ret = (DMaps[GET_REF(dmapdataref)].active_sub_script) * 10000; break;
6621 }
6622 case DMAPDATAMAPSCRIPT: //byte
6623 {
6624 ret = (DMaps[GET_REF(dmapdataref)].onmap_script) * 10000; break;
6625 }
6626 case DMAPDATAPSUBSCRIPT: //word
6627 {
6628 ret = (DMaps[GET_REF(dmapdataref)].passive_sub_script) * 10000; break;
6629 }
6630
6631 ///----------------------------------------------------------------------------------------------------//
6632 //messagedata msgd-> variables
6633 case MESSAGEDATANEXT: //W
6634 {
6635 int32_t ID = GET_REF(msgdataref);
6636
6637 if(BC::checkMessage(ID) != SH::_NoError)
6638 {
6639 ret = -10000; break;
6640 }
6641 else
6642 {
6643 ret = ((int32_t)MsgStrings[ID].nextstring) * 10000;
6644 break;
6645 }
6646 }
6647
6648 case MESSAGEDATATILE: //W
6649 {
6650 int32_t ID = GET_REF(msgdataref);
6651
6652 if(BC::checkMessage(ID) != SH::_NoError)
6653 ret = -10000;
6654 else
6655 ret = ((int32_t)MsgStrings[ID].tile) * 10000;
6656 break;
6657 }
6658
6659 case MESSAGEDATACSET: //b
6660 {
6661 int32_t ID = GET_REF(msgdataref);
6662
6663 if(BC::checkMessage(ID) != SH::_NoError)
6664 ret = -10000;
6665 else
6666 ret = ((int32_t)MsgStrings[ID].cset) * 10000;
6667 break;
6668 }
6669 case MESSAGEDATATRANS: //BOOL
6670 {
6671 int32_t ID = GET_REF(msgdataref);
6672
6673 if(BC::checkMessage(ID) != SH::_NoError)
6674 ret = -10000;
6675 else
6676 ret = ((MsgStrings[ID].trans)?10000:0);
6677 break;
6678 }
6679 case MESSAGEDATAFONT: //B
6680 {
6681 int32_t ID = GET_REF(msgdataref);
6682
6683 if(BC::checkMessage(ID) != SH::_NoError)
6684 ret = -10000;
6685 else
6686 ret = (int32_t)MsgStrings[ID].font * 10000;
6687 break;
6688 }
6689 case MESSAGEDATAX: //SHORT
6690 {
6691 int32_t ID = GET_REF(msgdataref);
6692
6693 if(BC::checkMessage(ID) != SH::_NoError)
6694 ret = -10000;
6695 else
6696 ret = ((int32_t)MsgStrings[ID].x) * 10000;
6697 break;
6698 }
6699 case MESSAGEDATAY: //SHORT
6700 {
6701 int32_t ID = GET_REF(msgdataref);
6702
6703 if(BC::checkMessage(ID) != SH::_NoError)
6704 ret = -10000;
6705 else
6706 ret = ((int32_t)MsgStrings[ID].y) * 10000;
6707 break;
6708 }
6709 case MESSAGEDATAW: //UNSIGNED SHORT
6710 {
6711 int32_t ID = GET_REF(msgdataref);
6712
6713 if(BC::checkMessage(ID) != SH::_NoError)
6714 ret = -10000;
6715 else
6716 ret = ((int32_t)MsgStrings[ID].w) * 10000;
6717 break;
6718 }
6719 case MESSAGEDATAH: //UNSIGNED SHORT
6720 {
6721 int32_t ID = GET_REF(msgdataref);
6722
6723 if(BC::checkMessage(ID) != SH::_NoError)
6724 ret = -10000;
6725 else
6726 ret = ((int32_t)MsgStrings[ID].h) * 10000;
6727 break;
6728 }
6729 case MESSAGEDATASFX: //BYTE
6730 {
6731 int32_t ID = GET_REF(msgdataref);
6732
6733 if(BC::checkMessage(ID) != SH::_NoError)
6734 ret = -10000;
6735 else
6736 ret = ((int32_t)MsgStrings[ID].sfx) * 10000;
6737 break;
6738 }
6739 case MESSAGEDATALISTPOS: //WORD
6740 {
6741 int32_t ID = GET_REF(msgdataref);
6742
6743 if(BC::checkMessage(ID) != SH::_NoError)
6744 ret = -10000;
6745 else
6746 ret = ((int32_t)MsgStrings[ID].listpos) * 10000;
6747 break;
6748 }
6749 case MESSAGEDATAVSPACE: //BYTE
6750 {
6751 int32_t ID = GET_REF(msgdataref);
6752
6753 if(BC::checkMessage(ID) != SH::_NoError)
6754 ret = -10000;
6755 else
6756 ret = ((int32_t)MsgStrings[ID].vspace) * 10000;
6757 break;
6758 }
6759 case MESSAGEDATAHSPACE: //BYTE
6760 {
6761 int32_t ID = GET_REF(msgdataref);
6762
6763 if(BC::checkMessage(ID) != SH::_NoError)
6764 ret = -10000;
6765 else
6766 ret = ((int32_t)MsgStrings[ID].hspace) * 10000;
6767 break;
6768 }
6769 case MESSAGEDATAFLAGS: //BYTE
6770 {
6771 int32_t ID = GET_REF(msgdataref);
6772
6773 if(BC::checkMessage(ID) != SH::_NoError)
6774 ret = -10000;
6775 else
6776 ret = ((int32_t)MsgStrings[ID].stringflags) * 10000;
6777 break;
6778 }
6779 case MESSAGEDATAPORTTILE: //INT
6780 {
6781 int32_t ID = GET_REF(msgdataref);
6782
6783 if(BC::checkMessage(ID) != SH::_NoError)
6784 ret = -10000;
6785 else
6786 ret = ((int32_t)MsgStrings[ID].portrait_tile) * 10000;
6787 break;
6788 }
6789 case MESSAGEDATAPORTCSET: //BYTE
6790 {
6791 int32_t ID = GET_REF(msgdataref);
6792
6793 if(BC::checkMessage(ID) != SH::_NoError)
6794 ret = -10000;
6795 else
6796 ret = ((int32_t)MsgStrings[ID].portrait_cset) * 10000;
6797 break;
6798 }
6799 case MESSAGEDATAPORTX: //BYTE
6800 {
6801 int32_t ID = GET_REF(msgdataref);
6802
6803 if(BC::checkMessage(ID) != SH::_NoError)
6804 ret = -10000;
6805 else
6806 ret = ((int32_t)MsgStrings[ID].portrait_x) * 10000;
6807 break;
6808 }
6809 case MESSAGEDATAPORTY: //BYTE
6810 {
6811 int32_t ID = GET_REF(msgdataref);
6812
6813 if(BC::checkMessage(ID) != SH::_NoError)
6814 ret = -10000;
6815 else
6816 ret = ((int32_t)MsgStrings[ID].portrait_y) * 10000;
6817 break;
6818 }
6819 case MESSAGEDATAPORTWID: //BYTE
6820 {
6821 int32_t ID = GET_REF(msgdataref);
6822
6823 if(BC::checkMessage(ID) != SH::_NoError)
6824 ret = -10000;
6825 else
6826 ret = ((int32_t)MsgStrings[ID].portrait_tw) * 10000;
6827 break;
6828 }
6829 case MESSAGEDATAPORTHEI: //BYTE
6830 {
6831 int32_t ID = GET_REF(msgdataref);
6832
6833 if(BC::checkMessage(ID) != SH::_NoError)
6834 ret = -10000;
6835 else
6836 ret = ((int32_t)MsgStrings[ID].portrait_th) * 10000;
6837 break;
6838 }
6839 case MESSAGEDATATEXTLEN: //BYTE
6840 {
6841 int32_t ID = GET_REF(msgdataref);
6842
6843 if(BC::checkMessage(ID) != SH::_NoError)
6844 ret = -10000;
6845 else
6846 ret = int32_t(MsgStrings[ID].s.size()) * 10000;
6847 break;
6848 }
6849 case MESSAGEDATATEXTWID:
6850 {
6851 ret = do_msgwidth(GET_REF(msgdataref))*10000;
6852 break;
6853 }
6854 case MESSAGEDATATEXTHEI:
6855 {
6856 ret = do_msgheight(GET_REF(msgdataref))*10000;
6857 break;
6858 }
6859
6860 ///----------------------------------------------------------------------------------------------------//
6861 //combodata cd-> Getter variables
6862 #define GET_COMBO_VAR_INT(member) \
6863 { \
6864 if(!checkComboRef()) \
6865 { \
6866 ret = -10000; \
6867 } \
6868 else \
6869 { \
6870 ret = (combobuf[GET_REF(combodataref)].member *10000); \
6871 } \
6872 } \
6873
6874 #define GET_COMBO_VAR_BYTE(member) \
6875 { \
6876 if(!checkComboRef()) \
6877 { \
6878 ret = -10000; \
6879 } \
6880 else \
6881 { \
6882 ret = (combobuf[GET_REF(combodataref)].member *10000); \
6883 } \
6884 } \
6885
6886 #define GET_COMBO_VAR_DWORD(member) \
6887 { \
6888 if(!checkComboRef()) \
6889 { \
6890 ret = -10000; \
6891 } \
6892 else \
6893 { \
6894 ret = (combobuf[GET_REF(combodataref)].member *10000); \
6895 } \
6896 } \
6897
6898 //comboclass macros
6899
6900 #define GET_COMBOCLASS_VAR_INT(member) \
6901 { \
6902 if(!checkComboRef()) \
6903 { \
6904 ret = -10000; \
6905 } \
6906 else \
6907 { \
6908 ret = (combo_class_buf[combobuf[GET_REF(combodataref)].type].member *10000); \
6909 } \
6910 } \
6911
6912 #define GET_COMBOCLASS_VAR_BYTE(member) \
6913 { \
6914 if(!checkComboRef()) \
6915 { \
6916 ret = -10000; \
6917 } \
6918 else \
6919 { \
6920 ret = (combo_class_buf[combobuf[GET_REF(combodataref)].type].member *10000); \
6921 } \
6922 } \
6923
6924 #define GET_COMBOCLASS_VAR_DWORD(member) \
6925 { \
6926 if(!checkComboRef()) \
6927 { \
6928 ret = -10000; \
6929 } \
6930 else \
6931 { \
6932 ret = (combo_class_buf[combobuf[GET_REF(combodataref)].type].member *10000); \
6933 } \
6934 } \
6935
6936 #define GET_COMBOCLASS_BYTE_INDEX(member, indexbound) \
6937 { \
6938 int32_t indx = GET_D(rINDEX) / 10000; \
6939 if(!checkComboRef()) \
6940 { \
6941 ret = -10000; \
6942 } \
6943 else if ( indx < 0 || indx > indexbound ) \
6944 { \
6945 scripting_log_error_with_context("Invalid Array Index: {}", indx); \
6946 ret = -10000; \
6947 } \
6948 else \
6949 { \
6950 ret = (combo_class_buf[combobuf[GET_REF(combodataref)].type].member[indx] * 100000); \
6951 } \
6952 }
6953
6954 case COMBOXR:
6955 {
6956
1/2
✓ Branch 0 taken 182307 times.
✗ Branch 1 not taken.
182307 if ( curScriptType == ScriptType::Combo )
6957 {
6958 182307 rpos_t rpos = combopos_ref_to_rpos(GET_REF(comboposref));
6959 182307 ret = (( COMBOX_REGION((rpos)) ) * 10000);
6960 //this may be wrong...may need a special new var for this, storing the exact combopos
6961 //i is the current script number
6962 182307 }
6963 else
6964 {
6965 scripting_log_error_with_context("Can only be called by combodata scripts, but you tried to use it from script type {}, name: {}", ScriptTypeToString(curScriptType), curscript->name());
6966 ret = -10000;
6967 }
6968 182307 break;
6969 }
6970
6971 case COMBOYR:
6972 {
6973
1/2
✓ Branch 0 taken 134178 times.
✗ Branch 1 not taken.
134178 if ( curScriptType == ScriptType::Combo )
6974 {
6975 134178 rpos_t rpos = combopos_ref_to_rpos(GET_REF(comboposref));
6976 134178 ret = (( COMBOY_REGION((rpos)) ) * 10000);
6977 134178 }
6978 else
6979 {
6980 scripting_log_error_with_context("Can only be called by combodata scripts, but you tried to use it from script type {}, name: {}", ScriptTypeToString(curScriptType), curscript->name());
6981 ret = -10000;
6982 }
6983 134178 break;
6984 }
6985 case COMBOPOSR:
6986 {
6987
1/2
✓ Branch 0 taken 629336 times.
✗ Branch 1 not taken.
629336 if ( curScriptType == ScriptType::Combo )
6988 {
6989 629336 rpos_t rpos = combopos_ref_to_rpos(GET_REF(comboposref));
6990 629336 ret = (int)rpos * 10000;
6991 629336 }
6992 else
6993 {
6994 scripting_log_error_with_context("Can only be called by combodata scripts, but you tried to use it from script type {}, name: {}", ScriptTypeToString(curScriptType), curscript->name());
6995 ret = -10000;
6996 }
6997 629336 break;
6998 }
6999 case COMBOLAYERR:
7000 {
7001
1/2
✓ Branch 0 taken 19185 times.
✗ Branch 1 not taken.
19185 if ( curScriptType == ScriptType::Combo )
7002 {
7003 19185 int32_t layer = combopos_ref_to_layer(GET_REF(comboposref));
7004 19185 ret = layer * 10000;
7005 19185 }
7006 else
7007 {
7008 scripting_log_error_with_context("Can only be called by combodata scripts, but you tried to use it from script type {}, name: {}", ScriptTypeToString(curScriptType), curscript->name());
7009 ret = -10000;
7010 }
7011 19185 break;
7012 }
7013
7014 //NEWCOMBO STRUCT
7015
1/2
✓ Branch 0 taken 116988 times.
✗ Branch 1 not taken.
116988 case COMBODTILE: GET_COMBO_VAR_DWORD(tile); break; //word
7016
1/2
✓ Branch 0 taken 122133 times.
✗ Branch 1 not taken.
122133 case COMBODOTILE: GET_COMBO_VAR_DWORD(o_tile); break; //word
7017
1/2
✓ Branch 0 taken 9711 times.
✗ Branch 1 not taken.
9711 case COMBODFRAME: GET_COMBO_VAR_BYTE(cur_frame); break; //char
7018 case COMBODACLK: GET_COMBO_VAR_BYTE(aclk); break; //char
7019
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 case COMBODASPEED: GET_COMBO_VAR_BYTE(speed); break; //char
7020
1/2
✓ Branch 0 taken 14257 times.
✗ Branch 1 not taken.
14257 case COMBODFLIP: GET_COMBO_VAR_BYTE(flip); break; //char
7021 case COMBODWALK:
7022 {
7023
1/2
✓ Branch 0 taken 6890 times.
✗ Branch 1 not taken.
6890 if(!checkComboRef())
7024 {
7025 ret = -10000;
7026 }
7027 else
7028 {
7029 6890 ret = ((combobuf[GET_REF(combodataref)].walk&0x0F) *10000);
7030 }
7031 6890 break;
7032 }
7033 case COMBODEFFECT:
7034 {
7035
1/2
✓ Branch 0 taken 755 times.
✗ Branch 1 not taken.
755 if(!checkComboRef())
7036 {
7037 ret = -10000;
7038 }
7039 else
7040 {
7041 755 ret = (((combobuf[GET_REF(combodataref)].walk&0xF0)>>4) *10000);
7042 }
7043 755 break;
7044 }
7045
1/2
✓ Branch 0 taken 12398 times.
✗ Branch 1 not taken.
12398 case COMBODTYPE: GET_COMBO_VAR_BYTE(type); break; //char
7046 case COMBODCSET:
7047 {
7048 if(!checkComboRef())
7049 {
7050 ret = -10000;
7051 }
7052 else
7053 {
7054 bool neg = combobuf[GET_REF(combodataref)].csets&0x8;
7055 ret = ((combobuf[GET_REF(combodataref)].csets&0x7) * (neg ? -10000 : 10000));
7056 }
7057 break;
7058 }
7059 case COMBODCSET2FLAGS:
7060 {
7061 if(checkComboRef())
7062 {
7063 ret = ((combobuf[GET_REF(combodataref)].csets & 0xF0) >> 4) * 10000;
7064 }
7065 break;
7066 }
7067 case COMBODFOO: break; //W
7068
1/2
✓ Branch 0 taken 528885 times.
✗ Branch 1 not taken.
528885 case COMBODATASCRIPT: GET_COMBO_VAR_DWORD(script); break; //W
7069
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 case COMBODFRAMES: GET_COMBO_VAR_BYTE(frames); break; //C
7070 case COMBODNEXTD: GET_COMBO_VAR_INT(nextcombo); break; //W
7071 case COMBODNEXTC: GET_COMBO_VAR_BYTE(nextcset); break; //C
7072 case COMBODFLAG: GET_COMBO_VAR_BYTE(flag); break; //C
7073 case COMBODSKIPANIM: GET_COMBO_VAR_BYTE(skipanim); break; //C
7074 case COMBODNEXTTIMER: GET_COMBO_VAR_DWORD(nexttimer); break; //W
7075 case COMBODAKIMANIMY: GET_COMBO_VAR_BYTE(skipanimy); break; //C
7076
1/2
✓ Branch 0 taken 5429248 times.
✗ Branch 1 not taken.
5429248 case COMBODANIMFLAGS: GET_COMBO_VAR_BYTE(animflags); break; //C
7077
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 case COMBODUSRFLAGS: GET_COMBO_VAR_INT(usrflags); break; //LONG
7078 case COMBODTRIGGERITEM:
7079 {
7080 ret = -10000;
7081 if (!checkComboRef()) break;
7082
7083 if(auto* trig = get_first_combo_trigger())
7084 ret = trig->triggeritem * 10000;
7085 break;
7086 }
7087 case COMBODTRIGGERTIMER:
7088 {
7089 ret = -10000;
7090 if (!checkComboRef()) break;
7091
7092 if(auto* trig = get_first_combo_trigger())
7093 ret = trig->trigtimer * 10000;
7094 break;
7095 }
7096 case COMBODTRIGGERSFX:
7097 {
7098 ret = -10000;
7099 if (!checkComboRef()) break;
7100
7101 if(auto* trig = get_first_combo_trigger())
7102 ret = trig->trigsfx * 10000;
7103 break;
7104 }
7105 case COMBODTRIGGERCHANGECMB:
7106 {
7107 ret = -10000;
7108 if (!checkComboRef()) break;
7109
7110 if(auto* trig = get_first_combo_trigger())
7111 ret = trig->trigchange * 10000;
7112 break;
7113 }
7114 case COMBODTRIGGERPROX:
7115 {
7116 ret = -10000;
7117 if (!checkComboRef()) break;
7118
7119 if(auto* trig = get_first_combo_trigger())
7120 ret = trig->trigprox * 10000;
7121 break;
7122 }
7123 case COMBODTRIGGERLIGHTBEAM:
7124 {
7125 ret = -10000;
7126 if (!checkComboRef()) break;
7127
7128 if(auto* trig = get_first_combo_trigger())
7129 ret = trig->triglbeam * 10000;
7130 break;
7131 }
7132 case COMBODTRIGGERCTR:
7133 {
7134 ret = -10000;
7135 if (!checkComboRef()) break;
7136
7137 if(auto* trig = get_first_combo_trigger())
7138 ret = trig->trigctr * 10000;
7139 break;
7140 }
7141 case COMBODTRIGGERCTRAMNT:
7142 {
7143 ret = -10000;
7144 if (!checkComboRef()) break;
7145
7146 if(auto* trig = get_first_combo_trigger())
7147 ret = trig->trigctramnt * 10000;
7148 break;
7149 }
7150 case COMBODTRIGGERCOOLDOWN:
7151 {
7152 ret = -10000;
7153 if (!checkComboRef()) break;
7154
7155 if(auto* trig = get_first_combo_trigger())
7156 ret = trig->trigcooldown * 10000;
7157 break;
7158 }
7159 case COMBODTRIGGERCOPYCAT:
7160 {
7161 ret = -10000;
7162 if (!checkComboRef()) break;
7163
7164 if(auto* trig = get_first_combo_trigger())
7165 ret = trig->trigcopycat * 10000;
7166 break;
7167 }
7168 case COMBODTRIGITEMPICKUP:
7169 {
7170 ret = -10000;
7171 if (!checkComboRef()) break;
7172
7173 if(auto* trig = get_first_combo_trigger())
7174 ret = trig->spawnip * 10000;
7175 break;
7176 }
7177 case COMBODTRIGEXSTATE:
7178 {
7179 ret = -10000;
7180 if (!checkComboRef()) break;
7181
7182 if(auto* trig = get_first_combo_trigger())
7183 ret = trig->exstate * 10000;
7184 break;
7185 }
7186 case COMBODTRIGEXDOORDIR:
7187 {
7188 ret = -10000;
7189 if (!checkComboRef()) break;
7190
7191 if(auto* trig = get_first_combo_trigger())
7192 ret = trig->exdoor_dir * 10000;
7193 break;
7194 }
7195 case COMBODTRIGEXDOORIND:
7196 {
7197 ret = -10000;
7198 if (!checkComboRef()) break;
7199
7200 if(auto* trig = get_first_combo_trigger())
7201 ret = trig->exdoor_ind * 10000;
7202 break;
7203 }
7204 case COMBODTRIGSPAWNENEMY:
7205 {
7206 ret = -10000;
7207 if (!checkComboRef()) break;
7208
7209 if(auto* trig = get_first_combo_trigger())
7210 ret = trig->spawnenemy * 10000;
7211 break;
7212 }
7213 case COMBODTRIGSPAWNITEM:
7214 {
7215 25 ret = -10000;
7216
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (!checkComboRef()) break;
7217
7218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if(auto* trig = get_first_combo_trigger())
7219 25 ret = trig->spawnitem * 10000;
7220 25 break;
7221 }
7222 case COMBODTRIGCSETCHANGE:
7223 {
7224 ret = -10000;
7225 if (!checkComboRef()) break;
7226
7227 if(auto* trig = get_first_combo_trigger())
7228 ret = trig->trigcschange * 10000;
7229 break;
7230 }
7231 case COMBODTRIGLITEMS:
7232 {
7233 ret = -10000;
7234 if (!checkComboRef()) break;
7235
7236 if(auto* trig = get_first_combo_trigger())
7237 ret = trig->trig_levelitems * 10000;
7238 break;
7239 }
7240 case COMBODTRIGDMAPLVL:
7241 {
7242 ret = -10000;
7243 if (!checkComboRef()) break;
7244
7245 if(auto* trig = get_first_combo_trigger())
7246 ret = trig->trigdmlevel * 10000;
7247 break;
7248 }
7249 case COMBODTRIGTINTR:
7250 {
7251 if (!checkComboRef()) break;
7252
7253 if(auto* trig = get_first_combo_trigger())
7254 ret = trig->trigtint[0] * 10000;
7255 break;
7256 }
7257 case COMBODTRIGTINTG:
7258 {
7259 if (!checkComboRef()) break;
7260
7261 if(auto* trig = get_first_combo_trigger())
7262 ret = trig->trigtint[1] * 10000;
7263 break;
7264 }
7265 case COMBODTRIGTINTB:
7266 {
7267 if (!checkComboRef()) break;
7268
7269 if(auto* trig = get_first_combo_trigger())
7270 ret = trig->trigtint[2] * 10000;
7271 break;
7272 }
7273 case COMBODTRIGLVLPAL:
7274 {
7275 ret = -10000;
7276 if (!checkComboRef()) break;
7277
7278 if(auto* trig = get_first_combo_trigger())
7279 ret = trig->triglvlpalette * 10000;
7280 break;
7281 }
7282 case COMBODTRIGBOSSPAL:
7283 {
7284 ret = -10000;
7285 if (!checkComboRef()) break;
7286
7287 if(auto* trig = get_first_combo_trigger())
7288 ret = trig->trigbosspalette * 10000;
7289 break;
7290 }
7291 case COMBODTRIGQUAKETIME:
7292 {
7293 ret = -10000;
7294 if (!checkComboRef()) break;
7295
7296 if(auto* trig = get_first_combo_trigger())
7297 ret = trig->trigquaketime * 10000;
7298 break;
7299 }
7300 case COMBODTRIGWAVYTIME:
7301 {
7302 ret = -10000;
7303 if (!checkComboRef()) break;
7304
7305 if(auto* trig = get_first_combo_trigger())
7306 ret = trig->trigwavytime * 10000;
7307 break;
7308 }
7309 case COMBODTRIGSWORDJINX:
7310 {
7311 ret = -10000;
7312 if (!checkComboRef()) break;
7313
7314 if(auto* trig = get_first_combo_trigger())
7315 ret = trig->trig_swjinxtime * 10000;
7316 break;
7317 }
7318 case COMBODTRIGITEMJINX:
7319 {
7320 ret = -10000;
7321 if (!checkComboRef()) break;
7322
7323 if(auto* trig = get_first_combo_trigger())
7324 ret = trig->trig_itmjinxtime * 10000;
7325 break;
7326 }
7327 case COMBODTRIGSHIELDJINX:
7328 {
7329 ret = -10000;
7330 if (!checkComboRef()) break;
7331
7332 if(auto* trig = get_first_combo_trigger())
7333 ret = trig->trig_shieldjinxtime * 10000;
7334 break;
7335 }
7336 case COMBODTRIGSTUN:
7337 {
7338 ret = -10000;
7339 if (!checkComboRef()) break;
7340
7341 if(auto* trig = get_first_combo_trigger())
7342 ret = trig->trig_stuntime * 10000;
7343 break;
7344 }
7345 case COMBODTRIGBUNNY:
7346 {
7347 ret = -10000;
7348 if (!checkComboRef()) break;
7349
7350 if(auto* trig = get_first_combo_trigger())
7351 ret = trig->trig_bunnytime * 10000;
7352 break;
7353 }
7354 case COMBODTRIGPUSHTIME:
7355 {
7356 ret = -10000;
7357 if (!checkComboRef()) break;
7358
7359 if(auto* trig = get_first_combo_trigger())
7360 ret = trig->trig_pushtime * 10000;
7361 break;
7362 }
7363 case COMBODLIFTGFXCOMBO:
7364 {
7365 ret = -10000;
7366 if (!checkComboRef()) break;
7367
7368 ret = (combobuf[GET_REF(combodataref)].liftcmb) * 10000;
7369 break;
7370 }
7371 case COMBODLIFTGFXCCSET:
7372 {
7373 ret = -10000;
7374 if (!checkComboRef()) break;
7375
7376 ret = (combobuf[GET_REF(combodataref)].liftcs) * 10000;
7377 break;
7378 }
7379 case COMBODLIFTUNDERCMB:
7380 {
7381 ret = -10000;
7382 if (!checkComboRef()) break;
7383
7384 ret = (combobuf[GET_REF(combodataref)].liftundercmb) * 10000;
7385 break;
7386 }
7387 case COMBODLIFTUNDERCS:
7388 {
7389 ret = -10000;
7390 if (!checkComboRef()) break;
7391
7392 ret = (combobuf[GET_REF(combodataref)].liftundercs) * 10000;
7393 break;
7394 }
7395 case COMBODLIFTDAMAGE:
7396 {
7397 ret = -10000;
7398 if (!checkComboRef()) break;
7399
7400 ret = (combobuf[GET_REF(combodataref)].liftdmg) * 10000;
7401 break;
7402 }
7403 case COMBODLIFTLEVEL:
7404 {
7405 ret = -10000;
7406 if (!checkComboRef()) break;
7407
7408 ret = (combobuf[GET_REF(combodataref)].liftlvl) * 10000;
7409 break;
7410 }
7411 case COMBODLIFTITEM:
7412 {
7413 ret = -10000;
7414 if (!checkComboRef()) break;
7415
7416 ret = (combobuf[GET_REF(combodataref)].liftitm) * 10000;
7417 break;
7418 }
7419 case COMBODLIFTGFXTYPE:
7420 {
7421 ret = -10000;
7422 if (!checkComboRef()) break;
7423
7424 ret = (combobuf[GET_REF(combodataref)].liftgfx) * 10000;
7425 break;
7426 }
7427 case COMBODLIFTGFXSPRITE:
7428 {
7429 ret = -10000;
7430 if (!checkComboRef()) break;
7431
7432 ret = (combobuf[GET_REF(combodataref)].liftsprite) * 10000;
7433 break;
7434 }
7435 case COMBODLIFTSFX:
7436 {
7437 ret = -10000;
7438 if (!checkComboRef()) break;
7439
7440 ret = (combobuf[GET_REF(combodataref)].liftsfx) * 10000;
7441 break;
7442 }
7443 case COMBODLIFTBREAKSPRITE:
7444 {
7445 ret = -10000;
7446 if (!checkComboRef()) break;
7447
7448 ret = (combobuf[GET_REF(combodataref)].liftbreaksprite) * 10000;
7449 break;
7450 }
7451 case COMBODLIFTBREAKSFX:
7452 {
7453 ret = -10000;
7454 if (!checkComboRef()) break;
7455
7456 ret = (combobuf[GET_REF(combodataref)].liftbreaksfx) * 10000;
7457 break;
7458 }
7459 case COMBODLIFTHEIGHT:
7460 {
7461 ret = -10000;
7462 if (!checkComboRef()) break;
7463
7464 ret = (combobuf[GET_REF(combodataref)].lifthei) * 10000;
7465 break;
7466 }
7467 case COMBODLIFTTIME:
7468 {
7469 ret = -10000;
7470 if (!checkComboRef()) break;
7471
7472 ret = (combobuf[GET_REF(combodataref)].lifttime) * 10000;
7473 break;
7474 }
7475 case COMBODLIFTLIGHTRAD:
7476 {
7477 ret = -10000;
7478 if (!checkComboRef()) break;
7479
7480 ret = (combobuf[GET_REF(combodataref)].lift_weap_data.light_rads[WPNSPR_BASE]) * 10000;
7481 break;
7482 }
7483 case COMBODLIFTLIGHTSHAPE:
7484 {
7485 ret = -10000;
7486 if (!checkComboRef()) break;
7487
7488 ret = (combobuf[GET_REF(combodataref)].lift_weap_data.glow_shape) * 10000;
7489 break;
7490 }
7491 case COMBODLIFTWEAPONITEM:
7492 {
7493 ret = -10000;
7494 if (!checkComboRef()) break;
7495
7496 ret = (combobuf[GET_REF(combodataref)].lift_parent_item) * 10000;
7497 break;
7498 }
7499 case COMBODTRIGGERLSTATE:
7500 {
7501 ret = -10000;
7502 if (!checkComboRef()) break;
7503
7504 if(auto* trig = get_first_combo_trigger())
7505 ret = trig->trig_lstate * 10000;
7506 break;
7507 }
7508 case COMBODTRIGGERGSTATE:
7509 {
7510 ret = -10000;
7511 if (!checkComboRef()) break;
7512
7513 if(auto* trig = get_first_combo_trigger())
7514 ret = trig->trig_gstate * 10000;
7515 break;
7516 }
7517 case COMBODTRIGGERGROUP:
7518 {
7519 ret = -10000;
7520 if (!checkComboRef()) break;
7521
7522 if(auto* trig = get_first_combo_trigger())
7523 ret = trig->trig_group * 10000;
7524 break;
7525 }
7526 case COMBODTRIGGERGROUPVAL:
7527 {
7528 ret = -10000;
7529 if (!checkComboRef()) break;
7530
7531 if(auto* trig = get_first_combo_trigger())
7532 ret = trig->trig_group_val * 10000;
7533 break;
7534 }
7535 case COMBODTRIGGERGTIMER:
7536 {
7537 ret = -10000;
7538 if (!checkComboRef()) break;
7539
7540 if(auto* trig = get_first_combo_trigger())
7541 ret = trig->trig_statetime * 10000;
7542 break;
7543 }
7544 case COMBODTRIGGERGENSCRIPT:
7545 {
7546 ret = -10000;
7547 if (!checkComboRef()) break;
7548
7549 if(auto* trig = get_first_combo_trigger())
7550 ret = trig->trig_genscr * 10000;
7551 break;
7552 }
7553
7554 case COMBODTRIGGERLEVEL:
7555 {
7556 ret = -10000;
7557 if (!checkComboRef()) break;
7558
7559 if(auto* trig = get_first_combo_trigger())
7560 ret = trig->triggerlevel * 10000;
7561 break;
7562 }
7563 5246834 case COMBODATAID: ret = (GET_REF(combodataref)*10000); break;
7564 case COMBODNUMTRIGGERS:
7565 {
7566 ret = -10000;
7567 if (!checkComboRef()) break;
7568
7569 ret = combobuf[GET_REF(combodataref)].triggers.size() * 10000;
7570 break;
7571 }
7572 case COMBODONLYGEN:
7573 {
7574 ret = 0;
7575 if (!checkComboRef()) break;
7576
7577 ret = combobuf[GET_REF(combodataref)].only_gentrig ? 10000 : 0;
7578 break;
7579 }
7580 case COMBOD_Z_HEIGHT:
7581 {
7582 ret = 0;
7583 if (!checkComboRef()) break;
7584
7585 ret = combobuf[GET_REF(combodataref)].z_height.getZLong();
7586 break;
7587 }
7588 case COMBOD_Z_STEP_HEIGHT:
7589 {
7590 ret = 0;
7591 if (!checkComboRef()) break;
7592
7593 ret = combobuf[GET_REF(combodataref)].z_step_height.getZLong();
7594 break;
7595 }
7596 case COMBOD_DIVE_UNDER_LEVEL:
7597 {
7598 ret = 0;
7599 if (!checkComboRef()) break;
7600
7601 ret = combobuf[GET_REF(combodataref)].dive_under_level * 10000;
7602 break;
7603 }
7604 //COMBOCLASS STRUCT
7605 //case COMBODNAME: //CHAR[64], STRING
7606 case COMBODBLOCKNPC: GET_COMBOCLASS_VAR_BYTE(block_enemies); break; //C
7607 case COMBODBLOCKHOLE: GET_COMBOCLASS_VAR_BYTE(block_hole); break; //C
7608 case COMBODBLOCKTRIG: GET_COMBOCLASS_VAR_BYTE(block_trigger); break; //C
7609 case COMBODBLOCKWEAPON: GET_COMBOCLASS_BYTE_INDEX(block_weapon, 32); break; //C, 32 INDICES
7610 case COMBODCONVXSPEED: GET_COMBOCLASS_VAR_DWORD(conveyor_x_speed); break; //SHORT
7611 case COMBODCONVYSPEED: GET_COMBOCLASS_VAR_DWORD(conveyor_y_speed); break; //SHORT
7612 case COMBODSPAWNNPC: GET_COMBOCLASS_VAR_DWORD(create_enemy); break; //W
7613 case COMBODSPAWNNPCWHEN: GET_COMBOCLASS_VAR_BYTE(create_enemy_when); break; //C
7614 case COMBODSPAWNNPCCHANGE: GET_COMBOCLASS_VAR_INT(create_enemy_change); break; //LONG
7615 case COMBODDIRCHANGETYPE: GET_COMBOCLASS_VAR_BYTE(directional_change_type); break; //C
7616 case COMBODDISTANCECHANGETILES: GET_COMBOCLASS_VAR_INT(distance_change_tiles); break; //LONG
7617 case COMBODDIVEITEM: GET_COMBOCLASS_VAR_DWORD(dive_item); break; //SHORT
7618 case COMBODDOCK: GET_COMBOCLASS_VAR_BYTE(dock); break; //C
7619 case COMBODFAIRY: GET_COMBOCLASS_VAR_BYTE(fairy); break; //C
7620 case COMBODFFATTRCHANGE: GET_COMBOCLASS_VAR_BYTE(ff_combo_attr_change); break; //C
7621 case COMBODFOORDECOTILE: GET_COMBOCLASS_VAR_INT(foot_decorations_tile); break; //LONG
7622 case COMBODFOORDECOTYPE: GET_COMBOCLASS_VAR_BYTE(foot_decorations_type); break; //C
7623 case COMBODHOOKSHOTPOINT: GET_COMBOCLASS_VAR_BYTE(hookshot_grab_point); break; //C
7624 case COMBODLADDERPASS: GET_COMBOCLASS_VAR_BYTE(ladder_pass); break; //C
7625 case COMBODLOCKBLOCK: GET_COMBOCLASS_VAR_BYTE(lock_block_type); break; //C
7626 case COMBODLOCKBLOCKCHANGE: GET_COMBOCLASS_VAR_INT(lock_block_change); break; //LONG
7627 case COMBODMAGICMIRROR: GET_COMBOCLASS_VAR_BYTE(magic_mirror_type); break; //C
7628 case COMBODMODHPAMOUNT: GET_COMBOCLASS_VAR_DWORD(modify_hp_amount); break; //SHORT
7629 case COMBODMODHPDELAY: GET_COMBOCLASS_VAR_BYTE(modify_hp_delay); break; //C
7630 case COMBODMODHPTYPE: GET_COMBOCLASS_VAR_BYTE(modify_hp_type); break; //C
7631 case COMBODNMODMPAMOUNT: GET_COMBOCLASS_VAR_DWORD(modify_mp_amount); break; //SHORT
7632 case COMBODMODMPDELAY: GET_COMBOCLASS_VAR_BYTE(modify_mp_delay); break; //C
7633 case COMBODMODMPTYPE: GET_COMBOCLASS_VAR_BYTE(modify_mp_type); break; //C
7634 case COMBODNOPUSHBLOCK: GET_COMBOCLASS_VAR_BYTE(no_push_blocks); break; //C
7635 case COMBODOVERHEAD: GET_COMBOCLASS_VAR_BYTE(overhead); break; //C
7636 case COMBODPLACENPC: GET_COMBOCLASS_VAR_BYTE(place_enemy); break; //C
7637 case COMBODPUSHDIR: GET_COMBOCLASS_VAR_BYTE(push_direction); break; //C
7638 case COMBODPUSHWAIT: GET_COMBOCLASS_VAR_BYTE(push_wait); break; //C
7639 case COMBODPUSHHEAVY: GET_COMBOCLASS_VAR_BYTE(push_weight); break; //C
7640 case COMBODPUSHED: GET_COMBOCLASS_VAR_BYTE(pushed); break; //C
7641 case COMBODRAFT: GET_COMBOCLASS_VAR_BYTE(raft); break; //C
7642 case COMBODRESETROOM: GET_COMBOCLASS_VAR_BYTE(reset_room); break; //C
7643 case COMBODSAVEPOINTTYPE: GET_COMBOCLASS_VAR_BYTE(save_point_type); break; //C
7644 case COMBODSCREENFREEZETYPE: GET_COMBOCLASS_VAR_BYTE(screen_freeze_type); break; //C
7645 case COMBODSECRETCOMBO: GET_COMBOCLASS_VAR_BYTE(secret_combo); break; //C
7646 case COMBODSINGULAR: GET_COMBOCLASS_VAR_BYTE(singular); break; //C
7647 case COMBODSLOWWALK: GET_COMBOCLASS_VAR_BYTE(slow_movement); break; //C
7648 case COMBODSTATUETYPE: GET_COMBOCLASS_VAR_BYTE(statue_type); break; //C
7649 case COMBODSTEPTYPE: GET_COMBOCLASS_VAR_BYTE(step_type); break; //C
7650 case COMBODSTEPCHANGEINTO: GET_COMBOCLASS_VAR_INT(step_change_to); break; //LONG
7651 case COMBODSTRIKEWEAPONS: GET_COMBOCLASS_BYTE_INDEX(strike_weapons, 32); break; //BYTE, 32 INDICES.
7652 case COMBODSTRIKEREMNANTS: GET_COMBOCLASS_VAR_INT(strike_remnants); break; //LONG
7653 case COMBODSTRIKEREMNANTSTYPE: GET_COMBOCLASS_VAR_BYTE(strike_remnants_type); break; //C
7654 case COMBODSTRIKECHANGE: GET_COMBOCLASS_VAR_INT(strike_change); break; //LONG
7655 case COMBODSTRIKEITEM: GET_COMBOCLASS_VAR_DWORD(strike_item); break; //SHORT
7656 case COMBODTOUCHITEM: GET_COMBOCLASS_VAR_DWORD(touch_item); break; //SHORT
7657 case COMBODTOUCHSTAIRS: GET_COMBOCLASS_VAR_BYTE(touch_stairs); break; //C
7658 case COMBODTRIGGERTYPE: GET_COMBOCLASS_VAR_BYTE(trigger_type); break; //C
7659 case COMBODTRIGGERSENS: GET_COMBOCLASS_VAR_BYTE(trigger_sensitive); break; //C
7660 case COMBODWARPTYPE: GET_COMBOCLASS_VAR_BYTE(warp_type); break; //C
7661 case COMBODWARPSENS: GET_COMBOCLASS_VAR_BYTE(warp_sensitive); break; //C
7662 case COMBODWARPDIRECT: GET_COMBOCLASS_VAR_BYTE(warp_direct); break; //C
7663 case COMBODWARPLOCATION: GET_COMBOCLASS_VAR_BYTE(warp_location); break; //C
7664 case COMBODWATER: GET_COMBOCLASS_VAR_BYTE(water); break; //C
7665 case COMBODWHISTLE: GET_COMBOCLASS_VAR_BYTE(whistle); break; //C
7666 case COMBODWINGAME: GET_COMBOCLASS_VAR_BYTE(win_game); break; //C
7667 case COMBODBLOCKWPNLEVEL: GET_COMBOCLASS_VAR_BYTE(block_weapon_lvl); break; //C
7668
7669
7670
7671 ///----------------------------------------------------------------------------------------------------//
7672 case CMBTRIGWPNLEVEL:
7673 {
7674 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7675 {
7676 ret = trig->triggerlevel * 10000;
7677 }
7678 else ret = -10000;
7679 break;
7680 }
7681 case CMBTRIGREQITEM:
7682 {
7683 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7684 {
7685 ret = trig->triggeritem * 10000;
7686 }
7687 else ret = -10000;
7688 break;
7689 }
7690 case CMBTRIGTIMER:
7691 {
7692 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7693 {
7694 ret = trig->trigtimer * 10000;
7695 }
7696 else ret = -10000;
7697 break;
7698 }
7699 case CMBTRIGSFX:
7700 {
7701 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7702 {
7703 ret = trig->trigsfx * 10000;
7704 }
7705 else ret = -10000;
7706 break;
7707 }
7708 case CMBTRIGCHANGECMB:
7709 {
7710 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7711 {
7712 ret = trig->trigchange * 10000;
7713 }
7714 else ret = -10000;
7715 break;
7716 }
7717 case CMBTRIGCSETCHANGE:
7718 {
7719 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7720 {
7721 ret = trig->trigcschange * 10000;
7722 }
7723 else ret = -10000;
7724 break;
7725 }
7726 case CMBTRIGPROX:
7727 {
7728 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7729 {
7730 ret = trig->trigprox * 10000;
7731 }
7732 else ret = -10000;
7733 break;
7734 }
7735 case CMBTRIGLIGHTBEAM:
7736 {
7737 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7738 {
7739 ret = trig->triglbeam * 10000;
7740 }
7741 else ret = -10000;
7742 break;
7743 }
7744 case CMBTRIGCTR:
7745 {
7746 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7747 {
7748 ret = trig->trigctr * 10000;
7749 }
7750 else ret = -10000;
7751 break;
7752 }
7753 case CMBTRIGCTRAMNT:
7754 {
7755 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7756 {
7757 ret = trig->trigctramnt * 10000;
7758 }
7759 else ret = -10000;
7760 break;
7761 }
7762 case CMBTRIGCOOLDOWN:
7763 {
7764 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7765 {
7766 ret = trig->trigcooldown * 10000;
7767 }
7768 else ret = -10000;
7769 break;
7770 }
7771 case CMBTRIGCOPYCAT:
7772 {
7773 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7774 {
7775 ret = trig->trigcopycat * 10000;
7776 }
7777 else ret = -10000;
7778 break;
7779 }
7780 case CMBTRIGITEMPICKUP:
7781 {
7782 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7783 {
7784 ret = trig->spawnip * 10000;
7785 }
7786 else ret = -10000;
7787 break;
7788 }
7789 case CMBTRIGEXSTATE:
7790 {
7791 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7792 {
7793 ret = trig->exstate * 10000;
7794 }
7795 else ret = -10000;
7796 break;
7797 }
7798 case CMBTRIGEXDOORDIR:
7799 {
7800 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7801 {
7802 ret = trig->exdoor_dir * 10000;
7803 }
7804 else ret = -10000;
7805 break;
7806 }
7807 case CMBTRIGEXDOORIND:
7808 {
7809 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7810 {
7811 ret = trig->exdoor_ind * 10000;
7812 }
7813 else ret = -10000;
7814 break;
7815 }
7816 case CMBTRIGSPAWNENEMY:
7817 {
7818 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7819 {
7820 ret = trig->spawnenemy * 10000;
7821 }
7822 else ret = -10000;
7823 break;
7824 }
7825 case CMBTRIGSPAWNITEM:
7826 {
7827 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7828 {
7829 ret = trig->spawnitem * 10000;
7830 }
7831 else ret = -10000;
7832 break;
7833 }
7834 case CMBTRIGLSTATE:
7835 {
7836 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7837 {
7838 ret = trig->trig_lstate * 10000;
7839 }
7840 else ret = -10000;
7841 break;
7842 }
7843 case CMBTRIGGSTATE:
7844 {
7845 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7846 {
7847 ret = trig->trig_gstate * 10000;
7848 }
7849 else ret = -10000;
7850 break;
7851 }
7852 case CMBTRIGGTIMER:
7853 {
7854 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7855 {
7856 ret = trig->trig_statetime * 10000;
7857 }
7858 else ret = -10000;
7859 break;
7860 }
7861 case CMBTRIGGENSCRIPT:
7862 {
7863 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7864 {
7865 ret = trig->trig_genscr * 10000;
7866 }
7867 else ret = -10000;
7868 break;
7869 }
7870 case CMBTRIGGROUP:
7871 {
7872 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7873 {
7874 ret = trig->trig_group * 10000;
7875 }
7876 else ret = -10000;
7877 break;
7878 }
7879 case CMBTRIGGROUPVAL:
7880 {
7881 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7882 {
7883 ret = trig->trig_group_val * 10000;
7884 }
7885 else ret = -10000;
7886 break;
7887 }
7888 case CMBTRIGLITEMS:
7889 {
7890 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7891 {
7892 ret = trig->trig_levelitems * 10000;
7893 }
7894 else ret = -10000;
7895 break;
7896 }
7897 case CMBTRIGDMAPLVL:
7898 {
7899 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7900 {
7901 ret = trig->trigdmlevel * 10000;
7902 }
7903 else ret = -10000;
7904 break;
7905 }
7906 case CMBTRIGTINTR:
7907 {
7908 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7909 {
7910 ret = trig->trigtint[0] * 10000;
7911 }
7912 else ret = -10000;
7913 break;
7914 }
7915 case CMBTRIGTINTG:
7916 {
7917 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7918 {
7919 ret = trig->trigtint[1] * 10000;
7920 }
7921 else ret = -10000;
7922 break;
7923 }
7924 case CMBTRIGTINTB:
7925 {
7926 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7927 {
7928 ret = trig->trigtint[2] * 10000;
7929 }
7930 else ret = -10000;
7931 break;
7932 }
7933 case CMBTRIGLVLPAL:
7934 {
7935 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7936 {
7937 ret = trig->triglvlpalette * 10000;
7938 }
7939 else ret = -10000;
7940 break;
7941 }
7942 case CMBTRIGBOSSPAL:
7943 {
7944 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7945 {
7946 ret = trig->trigbosspalette * 10000;
7947 }
7948 else ret = -10000;
7949 break;
7950 }
7951 case CMBTRIGQUAKETIME:
7952 {
7953 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7954 {
7955 ret = trig->trigquaketime * 10000;
7956 }
7957 else ret = -10000;
7958 break;
7959 }
7960 case CMBTRIGWAVYTIME:
7961 {
7962 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7963 {
7964 ret = trig->trigwavytime * 10000;
7965 }
7966 else ret = -10000;
7967 break;
7968 }
7969 case CMBTRIGSWORDJINX:
7970 {
7971 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7972 {
7973 ret = trig->trig_swjinxtime * 10000;
7974 }
7975 else ret = -10000;
7976 break;
7977 }
7978 case CMBTRIGITEMJINX:
7979 {
7980 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7981 {
7982 ret = trig->trig_itmjinxtime * 10000;
7983 }
7984 else ret = -10000;
7985 break;
7986 }
7987 case CMBTRIGSHIELDJINX:
7988 {
7989 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7990 {
7991 ret = trig->trig_shieldjinxtime * 10000;
7992 }
7993 else ret = -10000;
7994 break;
7995 }
7996 case CMBTRIGSTUN:
7997 {
7998 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
7999 {
8000 ret = trig->trig_stuntime * 10000;
8001 }
8002 else ret = -10000;
8003 break;
8004 }
8005 case CMBTRIGBUNNY:
8006 {
8007 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8008 {
8009 ret = trig->trig_bunnytime * 10000;
8010 }
8011 else ret = -10000;
8012 break;
8013 }
8014 case CMBTRIGPUSHTIME:
8015 {
8016 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8017 {
8018 ret = trig->trig_pushtime * 10000;
8019 }
8020 else ret = -10000;
8021 break;
8022 }
8023 case CMBTRIGGERPROMPTCID:
8024 {
8025 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8026 ret = trig->prompt_cid * 10000;
8027 else ret = -10000;
8028 break;
8029 }
8030 case CMBTRIGGERPROMPTCS:
8031 {
8032 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8033 ret = trig->prompt_cs * 10000;
8034 else ret = -10000;
8035 break;
8036 }
8037 case CMBTRIGGERFAILPROMPTCID:
8038 {
8039 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8040 ret = trig->fail_prompt_cid * 10000;
8041 else ret = -10000;
8042 break;
8043 }
8044 case CMBTRIGGERFAILPROMPTCS:
8045 {
8046 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8047 ret = trig->fail_prompt_cs * 10000;
8048 else ret = -10000;
8049 break;
8050 }
8051 case CMBTRIGGERPROMPTX:
8052 {
8053 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8054 ret = trig->prompt_x * 10000;
8055 else ret = -10000;
8056 break;
8057 }
8058 case CMBTRIGGERPROMPTY:
8059 {
8060 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8061 ret = trig->prompt_y * 10000;
8062 else ret = -10000;
8063 break;
8064 }
8065 case CMBTRIGGERTRIGSTR:
8066 {
8067 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8068 ret = trig->trig_msgstr * 10000;
8069 else ret = -10000;
8070 break;
8071 }
8072 case CMBTRIGGERFAILSTR:
8073 {
8074 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8075 ret = trig->fail_msgstr * 10000;
8076 else ret = -10000;
8077 break;
8078 }
8079 case CMBTRIGGERPLAYERBOUNCE:
8080 {
8081 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8082 ret = trig->player_bounce;
8083 else ret = -10000;
8084 break;
8085 }
8086 case CMBTRIGGERREQPLAYERZ:
8087 {
8088 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8089 ret = trig->req_player_z;
8090 else ret = -10000;
8091 break;
8092 }
8093 case CMBTRIGGERDESTHEROX:
8094 {
8095 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8096 ret = trig->dest_player_x;
8097 else ret = -10000;
8098 break;
8099 }
8100 case CMBTRIGGERDESTHEROY:
8101 {
8102 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8103 ret = trig->dest_player_y;
8104 else ret = -10000;
8105 break;
8106 }
8107 case CMBTRIGGERDESTHEROZ:
8108 {
8109 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8110 ret = trig->dest_player_z;
8111 else ret = -10000;
8112 break;
8113 }
8114 case CMBTRIGGERREQPLAYERJUMP:
8115 {
8116 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8117 ret = trig->req_player_jump;
8118 else ret = -10000;
8119 break;
8120 }
8121 case CMBTRIGGERREQPLAYERX:
8122 {
8123 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8124 ret = trig->req_player_x;
8125 else ret = -10000;
8126 break;
8127 }
8128 case CMBTRIGGERREQPLAYERY:
8129 {
8130 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8131 ret = trig->req_player_y;
8132 else ret = -10000;
8133 break;
8134 }
8135 case CMBTRIGGERFORCEPLAYERDIR:
8136 {
8137 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8138 ret = trig->dest_player_dir * 10000;
8139 else ret = -10000;
8140 break;
8141 }
8142 case CMBTRIGGERICECOMBO:
8143 {
8144 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8145 ret = trig->force_ice_combo * 10000;
8146 else ret = -10000;
8147 break;
8148 }
8149 case CMBTRIGGERICEVX:
8150 {
8151 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8152 ret = trig->force_ice_vx;
8153 else ret = -10000;
8154 break;
8155 }
8156 case CMBTRIGGERICEVY:
8157 {
8158 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8159 ret = trig->force_ice_vy;
8160 else ret = -10000;
8161 break;
8162 }
8163 case CMBTRIGGER_GRAVITY:
8164 {
8165 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8166 ret = trig->trig_gravity;
8167 else ret = -10000;
8168 break;
8169 break;
8170 }
8171 case CMBTRIGGER_TERMINAL_VELOCITY:
8172 {
8173 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
8174 ret = trig->trig_terminal_v;
8175 else ret = -10000;
8176 break;
8177 }
8178 ///----------------------------------------------------------------------------------------------------//
8179 //npcdata nd-> variables
8180
8181 //npcdata nd->member variable
8182 #define GET_NPCDATA_VAR_INT32(member, str) \
8183 { \
8184 if( !checkNPCDataRef() ) \
8185 { \
8186 ret = -10000; \
8187 } \
8188 else \
8189 { \
8190 ret = (guysbuf[GET_REF(npcdataref)].member *10000); \
8191 } \
8192 } \
8193
8194 #define GET_NPCDATA_VAR_BYTE(member, str) \
8195 { \
8196 if( !checkNPCDataRef() ) \
8197 { \
8198 ret = -10000; \
8199 } \
8200 else \
8201 { \
8202 ret = (guysbuf[GET_REF(npcdataref)].member *10000); \
8203 } \
8204 } \
8205
8206 #define GET_NPCDATA_VAR_INT16(member, str) \
8207 { \
8208 if( !checkNPCDataRef() ) \
8209 { \
8210 ret = -10000; \
8211 } \
8212 else \
8213 { \
8214 ret = (guysbuf[GET_REF(npcdataref)].member *10000); \
8215 } \
8216 } \
8217
8218 #define GET_NPCDATA_FLAG(member, str, indexbound) \
8219 { \
8220 int32_t flag = (value/10000); \
8221 if( !checkNPCDataRef() ) \
8222 { \
8223 } \
8224 else \
8225 { \
8226 ret = (guysbuf[ID].member&flag) ? 10000 : 0); \
8227 } \
8228 } \
8229
8230 // These are for compat only, though seemingly no quests even use these.
8231 case NPCDATAFLAGS1:
8232 {
8233 if( !checkNPCDataRef() )
8234 {
8235 ret = -10000;
8236 }
8237 else
8238 {
8239 uint32_t value = guysbuf[GET_REF(npcdataref)].flags & 0xFFFFFFFFLL;
8240 ret = value * 10000;
8241 }
8242 }
8243 break;
8244 case NPCDATAFLAGS2:
8245 {
8246 if( !checkNPCDataRef() )
8247 {
8248 ret = -10000;
8249 }
8250 else
8251 {
8252 uint32_t value = (guysbuf[GET_REF(npcdataref)].flags >> 32) & 0xFFFFFFFFLL;
8253 ret = value * 10000;
8254 }
8255 }
8256 break;
8257
8258 case NPCDATATILE: GET_NPCDATA_VAR_BYTE(tile, "Tile"); break;
8259 case NPCDATAWIDTH: GET_NPCDATA_VAR_BYTE(width, "Width"); break;
8260 case NPCDATAHEIGHT: GET_NPCDATA_VAR_BYTE(height, "Height"); break;
8261 case NPCDATASTILE: GET_NPCDATA_VAR_BYTE(s_tile, "STile"); break;
8262 case NPCDATASWIDTH: GET_NPCDATA_VAR_BYTE(s_width, "SWidth"); break;
8263 case NPCDATASHEIGHT: GET_NPCDATA_VAR_BYTE(s_height, "SHeight"); break;
8264
1/2
✓ Branch 0 taken 3182 times.
✗ Branch 1 not taken.
3182 case NPCDATAETILE: GET_NPCDATA_VAR_INT32(e_tile, "ExTile"); break;
8265 case NPCDATAEWIDTH: GET_NPCDATA_VAR_BYTE(e_width, "ExWidth"); break;
8266 case NPCDATAEHEIGHT: GET_NPCDATA_VAR_BYTE(e_height, "ExHeight"); break;
8267 case NPCDATAHP: GET_NPCDATA_VAR_INT16(hp, "HP"); break;
8268 case NPCDATATYPE: GET_NPCDATA_VAR_INT16(type, "Family"); break;
8269
1/2
✓ Branch 0 taken 3182 times.
✗ Branch 1 not taken.
3182 case NPCDATACSET: GET_NPCDATA_VAR_INT16(cset, "CSet"); break;
8270 case NPCDATAANIM: GET_NPCDATA_VAR_INT16(anim, "Anim"); break;
8271 case NPCDATAEANIM: GET_NPCDATA_VAR_INT16(e_anim, "ExAnim"); break;
8272 case NPCDATAFRAMERATE: GET_NPCDATA_VAR_INT16(frate, "Framerate"); break;
8273 case NPCDATAEFRAMERATE: GET_NPCDATA_VAR_INT16(e_frate, "ExFramerate"); break;
8274 case NPCDATATOUCHDAMAGE: GET_NPCDATA_VAR_INT16(dp, "TouchDamage"); break;
8275 case NPCDATAWEAPONDAMAGE: GET_NPCDATA_VAR_INT16(wdp, "WeaponDamage"); break;
8276 case NPCDATAWEAPON: GET_NPCDATA_VAR_INT16(weapon, "Weapon"); break;
8277 case NPCDATARANDOM: GET_NPCDATA_VAR_INT16(rate, "Random"); break;
8278 case NPCDATAHALT: GET_NPCDATA_VAR_INT16(hrate, "Haltrate"); break;
8279 case NPCDATASTEP: GET_NPCDATA_VAR_INT16(step, "Step"); break;
8280 case NPCDATAHOMING: GET_NPCDATA_VAR_INT16(homing, "Homing"); break;
8281 case NPCDATAHUNGER: GET_NPCDATA_VAR_INT16(grumble, "Hunger"); break;
8282 case NPCDATADROPSET: GET_NPCDATA_VAR_INT16(item_set, "Dropset"); break;
8283 case NPCDATABGSFX: GET_NPCDATA_VAR_INT16(bgsfx, "BGSFX"); break;
8284
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 case NPCDATADEATHSFX: GET_NPCDATA_VAR_BYTE(deadsfx, "DeathSFX"); break;
8285
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 case NPCDATAHITSFX: GET_NPCDATA_VAR_BYTE(hitsfx, "HitSFX"); break;
8286 case NPCDATAXOFS: GET_NPCDATA_VAR_INT32(xofs, "DrawXOffset"); break;
8287 case NPCDATAYOFS: GET_NPCDATA_VAR_INT32(yofs, "DrawYOffset"); break;
8288 case NPCDATAZOFS: GET_NPCDATA_VAR_INT32(zofs, "DrawZOffset"); break;
8289 case NPCDATAHXOFS: GET_NPCDATA_VAR_INT32(hxofs, "HitXOffset"); break;
8290 case NPCDATAHYOFS: GET_NPCDATA_VAR_INT32(hyofs, "HitYOffset"); break;
8291 case NPCDATAHITWIDTH: GET_NPCDATA_VAR_INT32(hxsz, "HitWidth"); break;
8292 case NPCDATAHITHEIGHT: GET_NPCDATA_VAR_INT32(hysz, "HitHeight"); break;
8293 case NPCDATAHITZ: GET_NPCDATA_VAR_INT32(hzsz, "HitZHeight"); break;
8294 case NPCDATASCRIPT: GET_NPCDATA_VAR_INT32(script, "Script"); break;
8295 case NPCDATATILEWIDTH: GET_NPCDATA_VAR_INT32(txsz, "TileWidth"); break;
8296 case NPCDATATILEHEIGHT: GET_NPCDATA_VAR_INT32(tysz, "TileHeight"); break;
8297 case NPCDATAWPNSPRITE: GET_NPCDATA_VAR_INT32(wpnsprite, "WeaponSprite"); break;
8298 case NPCDATAWEAPONSCRIPT:
8299 {
8300 if( (unsigned) ri->npcdataref > (MAXNPCS-1) )
8301 {
8302 Z_scripterrlog("Invalid NPC ID passed to npcdata->WeaponScript: %d\n", ri->npcdataref);
8303 ret = -10000;
8304 }
8305 else ret = (guysbuf[GET_REF(npcdataref)].weap_data.script *10000);
8306 break;
8307 }
8308 case NPCDATASIZEFLAG: GET_NPCDATA_VAR_INT32(SIZEflags, "SizeFlags"); break;
8309
8310 case NPCDATAFROZENTILE: GET_NPCDATA_VAR_INT32(frozentile, "FrozenTile"); break;
8311 case NPCDATAFROZENCSET: GET_NPCDATA_VAR_INT32(frozencset, "FrozenCSet"); break;
8312 case NPCDATAFIRESFX: GET_NPCDATA_VAR_BYTE(firesfx, "WeaponSFX"); break;
8313
8314 case NPCDSHADOWSPR:
8315 {
8316 if(!checkNPCDataRef())
8317 {
8318 Z_scripterrlog("Invalid NPC ID passed to npcdata->ShadowSprite: %d\n", ri->npcdataref);
8319 ret = -10000;
8320 }
8321 else
8322 {
8323 ret = guysbuf[GET_REF(npcdataref)].spr_shadow * 10000;
8324 }
8325 break;
8326 }
8327 case NPCDSPAWNSPR:
8328 {
8329 if(!checkNPCDataRef())
8330 {
8331 Z_scripterrlog("Invalid NPC ID passed to npcdata->SpawnSprite: %d\n", ri->npcdataref);
8332 ret = -10000;
8333 }
8334 else
8335 {
8336 ret = guysbuf[GET_REF(npcdataref)].spr_spawn * 10000;
8337 }
8338 break;
8339 }
8340 case NPCDDEATHSPR:
8341 {
8342 if(!checkNPCDataRef())
8343 {
8344 Z_scripterrlog("Invalid NPC ID passed to npcdata->DeathSprite: %d\n", ri->npcdataref);
8345 ret = -10000;
8346 }
8347 else
8348 {
8349 ret = guysbuf[GET_REF(npcdataref)].spr_death * 10000;
8350 }
8351 break;
8352 }
8353
8354 case NPCMATCHINITDLABEL: //Same form as SetScreenD()
8355 //bool npcdata->MatchInitDLabel("label", d)
8356 {
8357
8358 if( !checkNPCDataRef() ) \
8359 {
8360 Z_scripterrlog("Invalid NPC ID passed to npcdata->%s: %d\n", "MatchInitDLabel()", GET_REF(npcdataref));
8361 ret = 0;
8362 break;
8363 }
8364
8365 int32_t arrayptr = get_register(sarg1);
8366 int32_t init_d_index = get_register(sarg2) / 10000;
8367
8368 string name;
8369 ArrayH::getString(arrayptr, name, 256); // What's the limit on name length?
8370
8371 bool match = (!( strcmp(name.c_str(), guysbuf[GET_REF(npcdataref)].initD_label[init_d_index] )));
8372
8373 ret = ( match ? 10000 : 0 );
8374 break;
8375 }
8376
8377 ///----------------------------------------------------------------------------------------------------//
8378 //Dropset Variables
8379
8380 case DROPSETNULLCHANCE:
8381 {
8382 if(ri->dropsetdataref > MAXITEMDROPSETS)
8383 {
8384 Z_scripterrlog("Invalid dropset pointer %d\n", ri->dropsetdataref);
8385 ret = -10000;
8386 break;
8387 }
8388 ret = item_drop_sets[GET_REF(dropsetdataref)].chance[0] * 10000;
8389 break;
8390 }
8391 case DROPSETCHOOSE:
8392 {
8393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(ri->dropsetdataref > MAXITEMDROPSETS)
8394 {
8395 Z_scripterrlog("Invalid dropset pointer %d\n", ri->dropsetdataref);
8396 ret = -10000;
8397 break;
8398 }
8399 10 ret = select_dropitem(GET_REF(dropsetdataref)) * 10000;
8400 10 break;
8401 }
8402
8403 ///----------------------------------------------------------------------------------------------------//
8404 //Audio Variables
8405
8406 case AUDIOPAN:
8407 {
8408 ret = FFScript::do_getSFX_pan() * 10000;
8409 break;
8410 }
8411
8412 ///----------------------------------------------------------------------------------------------------//
8413 //Graphics->
8414
8415 case NUMDRAWS:
8416 ret = script_drawing_commands.Count() * 10000;
8417 //ret = FFCore.numscriptdraws * 10000; // This isn't updated until end of frame, making it useless!
8418 break;
8419
8420 case MAXDRAWS:
8421 ret = MAX_SCRIPT_DRAWING_COMMANDS * 10000;
8422 break;
8423
8424 case BITMAPWIDTH:
8425 {
8426
2/4
✓ Branch 0 taken 3453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3453 times.
✗ Branch 3 not taken.
3453 if (auto bmp = user_bitmaps.check(GET_REF(bitmapref)); bmp && bmp->u_bmp)
8427 {
8428 3453 ret = bmp->width * 10000;
8429 3453 }
8430 else
8431 {
8432 ret = -10000;
8433 }
8434 3453 break;
8435 }
8436
8437 case BITMAPHEIGHT:
8438 {
8439 if (auto bmp = user_bitmaps.check(GET_REF(bitmapref)); bmp && bmp->u_bmp)
8440 {
8441 ret = bmp->height * 10000;
8442 }
8443 else
8444 {
8445 ret = -10000;
8446 }
8447 break;
8448 }
8449
8450 ///----------------------------------------------------------------------------------------------------//
8451 //Stack->
8452 case STACKSIZE:
8453 {
8454 if(user_stack* st = checkStack(GET_REF(stackref), true))
8455 {
8456 ret = st->size(); //NOT *10000
8457 }
8458 else ret = -10000L;
8459 break;
8460 }
8461 case STACKFULL:
8462 {
8463 if(user_stack* st = checkStack(GET_REF(stackref), true))
8464 {
8465 ret = st->full() ? 10000L : 0L;
8466 }
8467 else ret = -10000L;
8468 break;
8469 }
8470
8471 ///----------------------------------------------------------------------------------------------------//
8472 //Misc./Internal
8473 case REFFFC:
8474
2/2
✓ Branch 0 taken 2523 times.
✓ Branch 1 taken 25922 times.
28445 ret = ZScriptVersion::ffcRefIsSpriteId() ? ri->ffcref : ri->ffcref * 10000;
8475 28445 break;
8476
8477 case REFITEM:
8478 608662 ret = ri->itemref;
8479 608662 break;
8480
8481 case REFITEMDATA:
8482 57964044 ret = ri->itemdataref;
8483 57964044 break;
8484
8485 case REFLWPN:
8486 2054459 ret = ri->lwpnref;
8487 2054459 break;
8488
8489 case REFEWPN:
8490 5970308 ret = ri->ewpnref;
8491 5970308 break;
8492
8493 case REFNPC:
8494 32182956 ret = ri->npcref;
8495 32182956 break;
8496
8497 case REFSPRITE:
8498 ret = ri->spriteref;
8499 break;
8500
8501 case REFMAPDATA: ret = ri->mapdataref; break;
8502 20 case REFSCREEN: ret = ri->screenref; break;
8503 5774191 case REFCOMBODATA: ret = ri->combodataref; break;
8504 case REFCOMBOTRIGGER: ret = ri->combotriggerref; break;
8505 5603 case REFSPRITEDATA: ret = ri->spritedataref; break;
8506 10 case REFBITMAP: ret = ri->bitmapref; break;
8507 2 case REFNPCDATA: ret = ri->npcdataref; break;
8508
8509
8510 549327 case REFDMAPDATA: ret = ri->dmapdataref; break;
8511 case REFSHOPDATA: ret = ri->shopdataref; break;
8512 54 case REFMSGDATA: ret = ri->msgdataref; break;
8513
8514 10 case REFDROPSETDATA: ret = ri->dropsetdataref; break;
8515 case REFBOTTLETYPE: ret = ri->bottletyperef; break;
8516 case REFBOTTLESHOP: ret = ri->bottleshopref; break;
8517 137856 case REFGENERICDATA: ret = ri->genericdataref; break;
8518 case REFFILE: ret = ri->fileref; break;
8519 case REFDIRECTORY: ret = ri->directoryref; break;
8520 case REFSTACK: ret = ri->stackref; break;
8521 91 case REFSUBSCREENDATA: ret = ri->subscreendataref; break;
8522 case REFSUBSCREENPAGE: ret = ri->subscreenpageref; break;
8523 case REFSUBSCREENWIDG: ret = ri->subscreenwidgref; break;
8524 case REFRNG: ret = ri->rngref; break;
8525 case REFWEBSOCKET: ret = ri->websocketref; break;
8526 733584 case CLASS_THISKEY: ret = ri->thiskey; break;
8527 1134 case CLASS_THISKEY2: ret = ri->thiskey2; break;
8528 case REFPALDATA: ret = ri->paldataref; break;
8529
8530
8531 case SP:
8532 ret = ri->sp * 10000;
8533 break;
8534 case SP2:
8535 279874 ret = ri->sp;
8536 279874 break;
8537
8538 case PC:
8539 ret = ri->pc;
8540 break;
8541
8542 case SWITCHKEY:
8543 ret = ri->switchkey;
8544 break;
8545
8546 case SCRIPTRAM:
8547 case GLOBALRAM:
8548 1125668249 ret = ArrayH::getElement(GET_D(rINDEX), GET_D(rINDEX2) / 10000);
8549 1125668249 break;
8550
8551 case SCRIPTRAMD:
8552 case GLOBALRAMD:
8553 ret = ArrayH::getElement(GET_D(rINDEX), 0);
8554 break;
8555
8556 case GDD: // Unused, remove?
8557 ret = read_array(game->global_d, GET_D(rINDEX) / 10000);
8558 break;
8559
8560 ///----------------------------------------------------------------------------------------------------//
8561
8562 case GENDATARUNNING:
8563 {
8564 7697 ret = 0;
8565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7697 times.
7697 if(user_genscript* scr = checkGenericScr(GET_REF(genericdataref)))
8566 {
8567 7697 ret = scr->doscript() ? 10000L : 0L;
8568 7697 }
8569 7697 break;
8570 }
8571 case GENDATASIZE:
8572 {
8573 ret = 0;
8574 if(user_genscript* scr = checkGenericScr(GET_REF(genericdataref)))
8575 {
8576 ret = scr->dataSize()*10000;
8577 }
8578 break;
8579 }
8580
8581 ///----------------------------------------------------------------------------------------------------//
8582
8583 case PORTALX:
8584 {
8585 ret = -10000;
8586 if(portal* p = checkPortal(GET_REF(portalref)))
8587 ret = p->x.getZLong();
8588 break;
8589 }
8590 case PORTALY:
8591 {
8592 ret = -10000;
8593 if(portal* p = checkPortal(GET_REF(portalref)))
8594 ret = p->y.getZLong();
8595 break;
8596 }
8597 case PORTALDMAP:
8598 {
8599 ret = -10000;
8600 if(portal* p = checkPortal(GET_REF(portalref)))
8601 ret = p->destdmap*10000;
8602 break;
8603 }
8604 case PORTALSCREEN:
8605 {
8606 ret = -10000;
8607 if(portal* p = checkPortal(GET_REF(portalref)))
8608 ret = p->destscr*10000;
8609 break;
8610 }
8611 case PORTALACLK:
8612 {
8613 ret = -10000;
8614 if(portal* p = checkPortal(GET_REF(portalref)))
8615 ret = p->aclk*10000;
8616 break;
8617 }
8618 case PORTALAFRM:
8619 {
8620 ret = -10000;
8621 if(portal* p = checkPortal(GET_REF(portalref)))
8622 ret = p->aframe*10000;
8623 break;
8624 }
8625 case PORTALOTILE:
8626 {
8627 ret = -10000;
8628 if(portal* p = checkPortal(GET_REF(portalref)))
8629 ret = p->o_tile*10000;
8630 break;
8631 }
8632 case PORTALASPD:
8633 {
8634 ret = -10000;
8635 if(portal* p = checkPortal(GET_REF(portalref)))
8636 ret = p->aspd*10000;
8637 break;
8638 }
8639 case PORTALFRAMES:
8640 {
8641 ret = -10000;
8642 if(portal* p = checkPortal(GET_REF(portalref)))
8643 ret = p->frames*10000;
8644 break;
8645 }
8646 case PORTALSAVED:
8647 {
8648 ret = 0;
8649 if(portal* p = checkPortal(GET_REF(portalref)))
8650 ret = p->saved_data;
8651 break;
8652 }
8653 case PORTALCLOSEDIS:
8654 {
8655 ret = 0;
8656 if(portal* p = checkPortal(GET_REF(portalref)))
8657 ret = p->prox_active ? 0 : 10000; //Inverted
8658 break;
8659 }
8660 case REFPORTAL:
8661 {
8662 ret = ri->portalref;
8663 break;
8664 }
8665 case REFSAVPORTAL:
8666 {
8667 ret = ri->savportalref;
8668 break;
8669 }
8670 case PORTALWARPSFX:
8671 {
8672 ret = 0;
8673 if(portal* p = checkPortal(GET_REF(portalref)))
8674 ret = p->wsfx ? 0 : 10000;
8675 break;
8676 }
8677 case PORTALWARPVFX:
8678 {
8679 ret = 0;
8680 if(portal* p = checkPortal(GET_REF(portalref)))
8681 ret = p->weffect ? 0 : 10000;
8682 break;
8683 }
8684 case SAVEDPORTALX:
8685 {
8686 ret = -10000;
8687 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8688 ret = p->x;
8689 break;
8690 }
8691 case SAVEDPORTALY:
8692 {
8693 ret = -10000;
8694 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8695 ret = p->y;
8696 break;
8697 }
8698 case SAVEDPORTALSRCDMAP:
8699 {
8700 ret = -10000;
8701 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8702 ret = p->srcdmap * 10000;
8703 break;
8704 }
8705 case SAVEDPORTALDESTDMAP:
8706 {
8707 ret = -10000;
8708 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8709 ret = p->destdmap * 10000;
8710 break;
8711 }
8712 case SAVEDPORTALSRCSCREEN:
8713 {
8714 ret = -10000;
8715 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8716 ret = p->srcscr * 10000;
8717 break;
8718 }
8719 case SAVEDPORTALDSTSCREEN:
8720 {
8721 ret = -10000;
8722 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8723 ret = p->destscr * 10000;
8724 break;
8725 }
8726 case SAVEDPORTALWARPSFX:
8727 {
8728 ret = -10000;
8729 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8730 ret = p->sfx * 10000;
8731 break;
8732 }
8733 case SAVEDPORTALWARPVFX:
8734 {
8735 ret = -10000;
8736 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8737 ret = p->warpfx * 10000;
8738 break;
8739 }
8740 case SAVEDPORTALSPRITE:
8741 {
8742 ret = -10000;
8743 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8744 ret = p->spr * 10000;
8745 break;
8746 }
8747 case SAVEDPORTALPORTAL:
8748 {
8749 ret = 0;
8750 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
8751 ret = getPortalFromSaved(p);
8752 break;
8753 }
8754 case PORTALCOUNT:
8755 {
8756 ret = portals.Count()*10000;
8757 break;
8758 }
8759 case SAVEDPORTALCOUNT:
8760 {
8761 ret = game->user_portals.size()*10000;
8762 break;
8763 }
8764
8765 case GAMEASUBOPEN:
8766 {
8767 ret = subscreen_open && !map_subscreen_open ? 10000 : 0;
8768 break;
8769 }
8770 case GAMEMSUBOPEN:
8771 {
8772 ret = subscreen_open && map_subscreen_open ? 10000 : 0;
8773 break;
8774 }
8775 case GAMEASUBYOFF:
8776 {
8777 47730 ret = active_sub_yoff*10000;
8778 47730 break;
8779 }
8780 case GAMENUMASUB:
8781 {
8782 ret = subscreens_active.size()*10000;
8783 break;
8784 }
8785 case GAMENUMPSUB:
8786 {
8787 ret = subscreens_passive.size()*10000;
8788 break;
8789 }
8790 case GAMENUMOSUB:
8791 {
8792 ret = subscreens_overlay.size()*10000;
8793 break;
8794 }
8795 case GAMENUMMSUB:
8796 {
8797 ret = subscreens_map.size()*10000;
8798 break;
8799 }
8800
8801 ///----------------------------------------------------------------------------------------------------//
8802
8803 case SUBDATACURPG:
8804 {
8805
2/4
✓ Branch 0 taken 54674 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54674 times.
54674 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
8806
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54674 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
109348 if (sub->sub_type == sstACTIVE || sub->sub_type == sstMAP)
8807 54674 ret = 10000*sub->curpage;
8808 54674 break;
8809 }
8810 case SUBDATANUMPG:
8811 {
8812
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
8813 {
8814
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11 if (sub->sub_type == sstACTIVE || sub->sub_type == sstMAP)
8815 11 ret = 10000*sub->pages.size();
8816 else ret = 10000;
8817 11 }
8818 11 break;
8819 }
8820 case SUBDATATYPE:
8821 {
8822 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
8823 ret = sub->sub_type*10000;
8824 break;
8825 }
8826
8827 ///---- ACTIVE SUBSCREENS ONLY
8828 case SUBDATACURSORPOS:
8829 {
8830 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8831 {
8832 SubscrPage& pg = sub->cur_page();
8833 ret = pg.cursor_pos * 10000;
8834 }
8835 break;
8836 }
8837 case SUBDATASCRIPT:
8838 {
8839 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8840 ret = sub->script * 10000;
8841 break;
8842 }
8843 case SUBDATATRANSLEFTTY:
8844 {
8845 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8846 {
8847 auto& trans = sub->trans_left;
8848 ret = trans.type * 10000;
8849 }
8850 break;
8851 }
8852 case SUBDATATRANSLEFTSFX:
8853 {
8854 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8855 {
8856 auto& trans = sub->trans_left;
8857 ret = trans.tr_sfx * 10000;
8858 }
8859 break;
8860 }
8861 case SUBDATATRANSRIGHTTY:
8862 {
8863 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8864 {
8865 auto& trans = sub->trans_right;
8866 ret = trans.type * 10000;
8867 }
8868 break;
8869 }
8870 case SUBDATATRANSRIGHTSFX:
8871 {
8872 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8873 {
8874 auto& trans = sub->trans_right;
8875 ret = trans.tr_sfx * 10000;
8876 }
8877 break;
8878 }
8879 case SUBDATASELECTORDSTX:
8880 {
8881 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8882 ret = sub->selector_setting.x * 10000;
8883 break;
8884 }
8885 case SUBDATASELECTORDSTY:
8886 {
8887 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8888 ret = sub->selector_setting.y * 10000;
8889 break;
8890 }
8891 case SUBDATASELECTORDSTW:
8892 {
8893 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8894 ret = sub->selector_setting.w * 10000;
8895 break;
8896 }
8897 case SUBDATASELECTORDSTH:
8898 {
8899 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8900 ret = sub->selector_setting.h * 10000;
8901 break;
8902 }
8903 ///---- CURRENTLY OPEN ACTIVE SUBSCREEN ONLY
8904 case SUBDATATRANSCLK:
8905 {
8906 5031 ret = -10000;
8907
3/6
✓ Branch 0 taken 5031 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5031 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5031 times.
5031 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8908 {
8909
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5031 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5031 times.
5031 if(sub != CURRENT_ACTIVE_SUBSCREEN)
8910 Z_scripterrlog("'subscreendata->TransClock' is only"
8911 " valid for the current active/map subscreen!\n");
8912
3/4
✓ Branch 0 taken 5031 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4855 times.
✓ Branch 3 taken 176 times.
5031 else if(subscreen_open && subscr_pg_animating)
8913 176 ret = subscr_pg_clk*10000;
8914 5031 }
8915 5031 break;
8916 }
8917 case SUBDATATRANSTY:
8918 {
8919 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8920 {
8921 auto& trans = subscr_pg_transition;
8922 if(sub != CURRENT_ACTIVE_SUBSCREEN)
8923 Z_scripterrlog("'subscreendata->TransType' is only"
8924 " valid for the current active/map subscreen!\n");
8925 else if(subscreen_open)
8926 ret = trans.type*10000;
8927 }
8928 break;
8929 }
8930 case SUBDATATRANSFROMPG:
8931 {
8932 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8933 {
8934 if(sub != CURRENT_ACTIVE_SUBSCREEN)
8935 Z_scripterrlog("'subscreendata->TransFromPage' is only"
8936 " valid for the current active/map subscreen!\n");
8937 else if(subscreen_open)
8938 ret = subscr_pg_from*10000;
8939 }
8940 break;
8941 }
8942 case SUBDATATRANSTOPG:
8943 {
8944 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
8945 {
8946 if(sub != CURRENT_ACTIVE_SUBSCREEN)
8947 Z_scripterrlog("'subscreendata->TransToPage' is only"
8948 " valid for the current active/map subscreen!\n");
8949 else if(subscreen_open)
8950 ret = subscr_pg_to*10000;
8951 }
8952 break;
8953 }
8954
8955 ///----------------------------------------------------------------------------------------------------//
8956 case SUBPGINDEX:
8957 {
8958 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
8959 ret = pg->getIndex() * 10000;
8960 break;
8961 }
8962 case SUBPGNUMWIDG:
8963 {
8964
2/4
✓ Branch 0 taken 1005 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1005 times.
1005 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
8965 1005 ret = pg->size() * 10000;
8966 1005 break;
8967 }
8968 case SUBPGSUBDATA:
8969 {
8970 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
8971 {
8972 auto [sub,ty,_pgid,_ind] = from_subref(GET_REF(subscreenpageref));
8973 ret = get_subref(sub,ty,0,0);
8974 }
8975 break;
8976 }
8977 case SUBPGCURSORPOS:
8978 {
8979
2/4
✓ Branch 0 taken 17326 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17326 times.
✗ Branch 3 not taken.
17326 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
8980 17326 ret = pg->cursor_pos * 10000;
8981 17326 break;
8982 }
8983 ///----------------------------------------------------------------------------------------------------//
8984 ///---- ANY WIDGET TYPE
8985 case SUBWIDGTYPE:
8986 {
8987
2/4
✓ Branch 0 taken 6024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6024 times.
✗ Branch 3 not taken.
6024 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
8988 6024 ret = 10000*widg->getType();
8989 6024 break;
8990 }
8991 case SUBWIDGINDEX:
8992 {
8993 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
8994 {
8995 auto [_sub,_ty,_pgid,ind] = from_subref(GET_REF(subscreenwidgref));
8996 ret = 10000*ind;
8997 }
8998 break;
8999 }
9000 case SUBWIDGDISPITM:
9001 {
9002
2/4
✓ Branch 0 taken 4206 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4206 times.
4206 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9003 {
9004 4206 ret = 10000*widg->getDisplayItem();
9005 4206 }
9006 4206 break;
9007 }
9008 case SUBWIDGEQPITM:
9009 {
9010
2/4
✓ Branch 0 taken 9836 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9836 times.
9836 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9011 {
9012 9836 ret = 10000*widg->getItemVal();
9013 9836 }
9014 9836 break;
9015 }
9016 case SUBWIDGPAGE:
9017 {
9018 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9019 {
9020 auto [sub,ty,pgid,_ind] = from_subref(GET_REF(subscreenwidgref));
9021 ret = get_subref(sub,ty,pgid,0);
9022 }
9023 break;
9024 }
9025 case SUBWIDGPOS:
9026 {
9027 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9028 ret = 10000*widg->pos;
9029 break;
9030 }
9031 case SUBWIDGX:
9032 {
9033
2/4
✓ Branch 0 taken 339 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 339 times.
✗ Branch 3 not taken.
339 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9034 339 ret = 10000*widg->x;
9035 339 break;
9036 }
9037 case SUBWIDGY:
9038 {
9039
2/4
✓ Branch 0 taken 339 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 339 times.
339 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9040 339 ret = 10000*widg->y;
9041 339 break;
9042 }
9043 case SUBWIDGW:
9044 {
9045 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9046 ret = 10000*widg->w;
9047 break;
9048 }
9049 case SUBWIDGH:
9050 {
9051 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9052 ret = 10000*widg->h;
9053 break;
9054 }
9055 case SUBWIDG_DISPX:
9056 {
9057 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9058 ret = 10000*widg->getX();
9059 break;
9060 }
9061 case SUBWIDG_DISPY:
9062 {
9063 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9064 ret = 10000*widg->getY();
9065 break;
9066 }
9067 case SUBWIDG_DISPW:
9068 {
9069 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9070 ret = 10000*widg->getW();
9071 break;
9072 }
9073 case SUBWIDG_DISPH:
9074 {
9075 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9076 ret = 10000*widg->getH();
9077 break;
9078 }
9079 case SUBWIDGREQCOUNTER:
9080 {
9081 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9082 ret = 10000 * widg->req_counter;
9083 break;
9084 }
9085 case SUBWIDGREQCOUNTERCOND:
9086 {
9087 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9088 ret = 10000 * widg->req_counter_cond_type;
9089 break;
9090 }
9091 case SUBWIDGREQCOUNTERVAL:
9092 {
9093 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9094 ret = 10000 * widg->req_counter_val;
9095 break;
9096 }
9097 case SUBWIDGREQLITEMS:
9098 {
9099 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9100 ret = 10000 * widg->req_litems;
9101 break;
9102 }
9103 case SUBWIDGREQLITEMLEVEL:
9104 {
9105 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9106 ret = 10000 * widg->req_litem_level;
9107 break;
9108 }
9109 case SUBWIDGREQ_LEVEL_STATE_LEVEL:
9110 {
9111 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9112 ret = 10000 * widg->req_lstate_level;
9113 break;
9114 }
9115 case SUBWIDGREQ_SCRSTATE_MAP:
9116 {
9117 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9118 ret = 10000 * widg->req_scrstate_map;
9119 break;
9120 }
9121 case SUBWIDGREQ_SCRSTATE_SCREEN:
9122 {
9123 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9124 ret = 10000 * widg->req_scrstate_scr;
9125 break;
9126 }
9127 case SUBWIDGREQSCRIPTDISABLED:
9128 {
9129 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9130 ret = widg->is_disabled ? 10000 : 0;
9131 break;
9132 }
9133 ///---- ACTIVE SUBSCREENS ONLY
9134 case SUBWIDGSELECTORDSTX:
9135 {
9136 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9137 ret = 10000*widg->selector_override.x;
9138 break;
9139 }
9140 case SUBWIDGSELECTORDSTY:
9141 {
9142 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9143 ret = 10000*widg->selector_override.y;
9144 break;
9145 }
9146 case SUBWIDGSELECTORDSTW:
9147 {
9148 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9149 ret = 10000*widg->selector_override.w;
9150 break;
9151 }
9152 case SUBWIDGSELECTORDSTH:
9153 {
9154 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9155 ret = 10000*widg->selector_override.h;
9156 break;
9157 }
9158
9159 case SUBWIDGPRESSSCRIPT:
9160 {
9161 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9162 ret = 10000*widg->generic_script;
9163 break;
9164 }
9165 case SUBWIDGPGMODE:
9166 {
9167 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9168 ret = 10000*widg->pg_mode;
9169 break;
9170 }
9171 case SUBWIDGPGTARG:
9172 {
9173 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9174 ret = 10000*widg->pg_targ;
9175 break;
9176 }
9177
9178 case SUBWIDGTRANSPGTY:
9179 {
9180 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9181 {
9182 auto& trans = widg->pg_trans;
9183 ret = 10000*trans.type;
9184 }
9185 break;
9186 }
9187 case SUBWIDGTRANSPGSFX:
9188 {
9189 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
9190 {
9191 auto& trans = widg->pg_trans;
9192 ret = 10000*trans.tr_sfx;
9193 }
9194 break;
9195 }
9196 ///---- VARYING WIDGET TYPES
9197 case SUBWIDGTY_FONT:
9198 {
9199 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9200 {
9201 auto ty = widg->getType();
9202 switch(ty)
9203 {
9204 case widgTEXT:
9205 ret = 10000*((SW_Text*)widg)->fontid;
9206 break;
9207 case widgITMCOOLDOWNTEXT:
9208 ret = 10000*((SW_ItemCooldownText*)widg)->fontid;
9209 break;
9210 case widgTEXTBOX:
9211 ret = 10000*((SW_TextBox*)widg)->fontid;
9212 break;
9213 case widgSELECTEDTEXT:
9214 ret = 10000*((SW_SelectedText*)widg)->fontid;
9215 break;
9216 case widgTIME:
9217 ret = 10000*((SW_Time*)widg)->fontid;
9218 break;
9219 case widgCOUNTER:
9220 ret = 10000*((SW_Counter*)widg)->fontid;
9221 break;
9222 case widgBTNCOUNTER:
9223 ret = 10000*((SW_BtnCounter*)widg)->fontid;
9224 break;
9225 case widgOLDCTR:
9226 ret = 10000*((SW_Counters*)widg)->fontid;
9227 break;
9228 case widgMMAPTITLE:
9229 ret = 10000*((SW_MMapTitle*)widg)->fontid;
9230 break;
9231 default:
9232 bad_subwidg_type(false, ty);
9233 ret = -10000;
9234 break;
9235 }
9236 }
9237 break;
9238 }
9239 case SUBWIDGTY_ALIGN:
9240 {
9241 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9242 {
9243 auto ty = widg->getType();
9244 switch(ty)
9245 {
9246 case widgTEXT:
9247 ret = 10000*((SW_Text*)widg)->align;
9248 break;
9249 case widgITMCOOLDOWNTEXT:
9250 ret = 10000*((SW_ItemCooldownText*)widg)->align;
9251 break;
9252 case widgTEXTBOX:
9253 ret = 10000*((SW_TextBox*)widg)->align;
9254 break;
9255 case widgSELECTEDTEXT:
9256 ret = 10000*((SW_SelectedText*)widg)->align;
9257 break;
9258 case widgTIME:
9259 ret = 10000*((SW_Time*)widg)->align;
9260 break;
9261 case widgCOUNTER:
9262 ret = 10000*((SW_Counter*)widg)->align;
9263 break;
9264 case widgBTNCOUNTER:
9265 ret = 10000*((SW_BtnCounter*)widg)->align;
9266 break;
9267 case widgMMAPTITLE:
9268 ret = 10000*((SW_MMapTitle*)widg)->align;
9269 break;
9270 default:
9271 bad_subwidg_type(false, ty);
9272 ret = -10000;
9273 break;
9274 }
9275 }
9276 break;
9277 }
9278 case SUBWIDGTY_SHADOWTY:
9279 {
9280 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9281 {
9282 auto ty = widg->getType();
9283 switch(ty)
9284 {
9285 case widgTEXT:
9286 ret = 10000*((SW_Text*)widg)->shadtype;
9287 break;
9288 case widgITMCOOLDOWNTEXT:
9289 ret = 10000*((SW_ItemCooldownText*)widg)->shadtype;
9290 break;
9291 case widgTEXTBOX:
9292 ret = 10000*((SW_TextBox*)widg)->shadtype;
9293 break;
9294 case widgSELECTEDTEXT:
9295 ret = 10000*((SW_SelectedText*)widg)->shadtype;
9296 break;
9297 case widgTIME:
9298 ret = 10000*((SW_Time*)widg)->shadtype;
9299 break;
9300 case widgCOUNTER:
9301 ret = 10000*((SW_Counter*)widg)->shadtype;
9302 break;
9303 case widgBTNCOUNTER:
9304 ret = 10000*((SW_BtnCounter*)widg)->shadtype;
9305 break;
9306 case widgOLDCTR:
9307 ret = 10000*((SW_Counters*)widg)->shadtype;
9308 break;
9309 case widgMMAPTITLE:
9310 ret = 10000*((SW_MMapTitle*)widg)->shadtype;
9311 break;
9312 default:
9313 bad_subwidg_type(false, ty);
9314 ret = -10000;
9315 break;
9316 }
9317 }
9318 break;
9319 }
9320 case SUBWIDGTY_COLOR_TXT:
9321 {
9322 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9323 {
9324 auto ty = widg->getType();
9325 switch(ty)
9326 {
9327 case widgTEXT:
9328 ret = 10000*((SW_Text*)widg)->c_text.get_int_color();
9329 break;
9330 case widgITMCOOLDOWNTEXT:
9331 ret = 10000*((SW_ItemCooldownText*)widg)->c_text.get_int_color();
9332 break;
9333 case widgTEXTBOX:
9334 ret = 10000*((SW_TextBox*)widg)->c_text.get_int_color();
9335 break;
9336 case widgSELECTEDTEXT:
9337 ret = 10000*((SW_SelectedText*)widg)->c_text.get_int_color();
9338 break;
9339 case widgTIME:
9340 ret = 10000*((SW_Time*)widg)->c_text.get_int_color();
9341 break;
9342 case widgCOUNTER:
9343 ret = 10000*((SW_Counter*)widg)->c_text.get_int_color();
9344 break;
9345 case widgBTNCOUNTER:
9346 ret = 10000*((SW_BtnCounter*)widg)->c_text.get_int_color();
9347 break;
9348 case widgOLDCTR:
9349 ret = 10000*((SW_Counters*)widg)->c_text.get_int_color();
9350 break;
9351 case widgMMAPTITLE:
9352 ret = 10000*((SW_MMapTitle*)widg)->c_text.get_int_color();
9353 break;
9354 case widgMCGUFF_FRAME:
9355 ret = 10000*((SW_TriFrame*)widg)->c_number.get_int_color();
9356 break;
9357 default:
9358 bad_subwidg_type(false, ty);
9359 break;
9360 }
9361 }
9362 break;
9363 }
9364 case SUBWIDGTY_COLOR_SHD:
9365 {
9366 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9367 {
9368 auto ty = widg->getType();
9369 switch(ty)
9370 {
9371 case widgTEXT:
9372 ret = 10000*((SW_Text*)widg)->c_shadow.get_int_color();
9373 break;
9374 case widgITMCOOLDOWNTEXT:
9375 ret = 10000*((SW_ItemCooldownText*)widg)->c_shadow.get_int_color();
9376 break;
9377 case widgTEXTBOX:
9378 ret = 10000*((SW_TextBox*)widg)->c_shadow.get_int_color();
9379 break;
9380 case widgSELECTEDTEXT:
9381 ret = 10000*((SW_SelectedText*)widg)->c_shadow.get_int_color();
9382 break;
9383 case widgTIME:
9384 ret = 10000*((SW_Time*)widg)->c_shadow.get_int_color();
9385 break;
9386 case widgCOUNTER:
9387 ret = 10000*((SW_Counter*)widg)->c_shadow.get_int_color();
9388 break;
9389 case widgBTNCOUNTER:
9390 ret = 10000*((SW_BtnCounter*)widg)->c_shadow.get_int_color();
9391 break;
9392 case widgOLDCTR:
9393 ret = 10000*((SW_Counters*)widg)->c_shadow.get_int_color();
9394 break;
9395 case widgMMAPTITLE:
9396 ret = 10000*((SW_MMapTitle*)widg)->c_shadow.get_int_color();
9397 break;
9398 default:
9399 bad_subwidg_type(false, ty);
9400 break;
9401 }
9402 }
9403 break;
9404 }
9405 case SUBWIDGTY_COLOR_BG:
9406 {
9407 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9408 {
9409 auto ty = widg->getType();
9410 switch(ty)
9411 {
9412 case widgTEXT:
9413 ret = 10000*((SW_Text*)widg)->c_bg.get_int_color();
9414 break;
9415 case widgITMCOOLDOWNTEXT:
9416 ret = 10000*((SW_ItemCooldownText*)widg)->c_bg.get_int_color();
9417 break;
9418 case widgTEXTBOX:
9419 ret = 10000*((SW_TextBox*)widg)->c_bg.get_int_color();
9420 break;
9421 case widgSELECTEDTEXT:
9422 ret = 10000*((SW_SelectedText*)widg)->c_bg.get_int_color();
9423 break;
9424 case widgTIME:
9425 ret = 10000*((SW_Time*)widg)->c_bg.get_int_color();
9426 break;
9427 case widgCOUNTER:
9428 ret = 10000*((SW_Counter*)widg)->c_bg.get_int_color();
9429 break;
9430 case widgBTNCOUNTER:
9431 ret = 10000*((SW_BtnCounter*)widg)->c_bg.get_int_color();
9432 break;
9433 case widgOLDCTR:
9434 ret = 10000*((SW_Counters*)widg)->c_bg.get_int_color();
9435 break;
9436 case widgMMAPTITLE:
9437 ret = 10000*((SW_MMapTitle*)widg)->c_bg.get_int_color();
9438 break;
9439 case widgBGCOLOR:
9440 ret = 10000*((SW_Clear*)widg)->c_bg.get_int_color();
9441 break;
9442 case widgCOUNTERPERCBAR:
9443 ret = 10000*((SW_CounterPercentBar*)widg)->c_bg.get_int_color();
9444 break;
9445 default:
9446 bad_subwidg_type(false, ty);
9447 break;
9448 }
9449 }
9450 break;
9451 }
9452
9453 case SUBWIDGTY_COLOR_TXT2:
9454 {
9455 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9456 {
9457 auto ty = widg->getType();
9458 switch(ty)
9459 {
9460 case widgCOUNTER:
9461 ret = 10000*((SW_Counter*)widg)->c_text2.get_int_color();
9462 break;
9463 case widgBTNCOUNTER:
9464 ret = 10000*((SW_BtnCounter*)widg)->c_text2.get_int_color();
9465 break;
9466 default:
9467 bad_subwidg_type(false, ty);
9468 break;
9469 }
9470 }
9471 break;
9472 }
9473 case SUBWIDGTY_COLOR_SHD2:
9474 {
9475 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9476 {
9477 auto ty = widg->getType();
9478 switch(ty)
9479 {
9480 case widgCOUNTER:
9481 ret = 10000*((SW_Counter*)widg)->c_shadow2.get_int_color();
9482 break;
9483 case widgBTNCOUNTER:
9484 ret = 10000*((SW_BtnCounter*)widg)->c_shadow2.get_int_color();
9485 break;
9486 default:
9487 bad_subwidg_type(false, ty);
9488 break;
9489 }
9490 }
9491 break;
9492 }
9493 case SUBWIDGTY_COLOR_BG2:
9494 {
9495 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9496 {
9497 auto ty = widg->getType();
9498 switch(ty)
9499 {
9500 case widgCOUNTER:
9501 ret = 10000*((SW_Counter*)widg)->c_bg2.get_int_color();
9502 break;
9503 case widgBTNCOUNTER:
9504 ret = 10000*((SW_BtnCounter*)widg)->c_bg2.get_int_color();
9505 break;
9506 default:
9507 bad_subwidg_type(false, ty);
9508 break;
9509 }
9510 }
9511 break;
9512 }
9513 case SUBWIDGTY_COLOR_OLINE:
9514 {
9515 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9516 {
9517 auto ty = widg->getType();
9518 switch(ty)
9519 {
9520 case widgLINE:
9521 ret = 10000*((SW_Line*)widg)->c_line.get_int_color();
9522 break;
9523 case widgRECT:
9524 ret = 10000*((SW_Rect*)widg)->c_outline.get_int_color();
9525 break;
9526 case widgMCGUFF_FRAME:
9527 ret = 10000*((SW_TriFrame*)widg)->c_outline.get_int_color();
9528 break;
9529 default:
9530 bad_subwidg_type(false, ty);
9531 break;
9532 }
9533 }
9534 break;
9535 }
9536 case SUBWIDGTY_COLOR_FILL:
9537 {
9538 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9539 {
9540 auto ty = widg->getType();
9541 switch(ty)
9542 {
9543 case widgRECT:
9544 ret = 10000*((SW_Rect*)widg)->c_fill.get_int_color();
9545 break;
9546 case widgCOUNTERPERCBAR:
9547 ret = 10000*((SW_CounterPercentBar*)widg)->c_fill.get_int_color();
9548 break;
9549 default:
9550 bad_subwidg_type(false, ty);
9551 break;
9552 }
9553 }
9554 break;
9555 }
9556 case SUBWIDGTY_BUTTON:
9557 {
9558 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9559 {
9560 auto ty = widg->getType();
9561 switch(ty)
9562 {
9563 case widgBTNITM:
9564 ret = 10000*((SW_ButtonItem*)widg)->btn;
9565 break;
9566 case widgBTNCOUNTER:
9567 ret = 10000*((SW_BtnCounter*)widg)->btn;
9568 break;
9569 case widgITMCOOLDOWNGAUGE:
9570 ret = 10000*((SW_ItemCooldownGauge*)widg)->button_id;
9571 break;
9572 case widgITMCOOLDOWNTEXT:
9573 ret = 10000*((SW_ItemCooldownText*)widg)->button_id;
9574 break;
9575 default:
9576 bad_subwidg_type(false, ty);
9577 ret = -10000;
9578 break;
9579 }
9580 }
9581 break;
9582 }
9583 case SUBWIDGTY_MINDIG:
9584 {
9585 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9586 {
9587 auto ty = widg->getType();
9588 switch(ty)
9589 {
9590 case widgCOUNTER:
9591 ret = 10000*((SW_Counter*)widg)->mindigits;
9592 break;
9593 case widgBTNCOUNTER:
9594 ret = 10000*((SW_BtnCounter*)widg)->mindigits;
9595 break;
9596 case widgOLDCTR:
9597 ret = 10000*((SW_Counters*)widg)->digits;
9598 break;
9599 default:
9600 bad_subwidg_type(false, ty);
9601 ret = -10000;
9602 break;
9603 }
9604 }
9605 break;
9606 }
9607 case SUBWIDGTY_MAXDIG:
9608 {
9609 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9610 {
9611 auto ty = widg->getType();
9612 switch(ty)
9613 {
9614 case widgCOUNTER:
9615 ret = 10000*((SW_Counter*)widg)->maxdigits;
9616 break;
9617 case widgBTNCOUNTER:
9618 ret = 10000*((SW_BtnCounter*)widg)->maxdigits;
9619 break;
9620 default:
9621 bad_subwidg_type(false, ty);
9622 ret = -10000;
9623 break;
9624 }
9625 }
9626 break;
9627 }
9628 case SUBWIDGTY_INFITM:
9629 {
9630 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9631 {
9632 auto ty = widg->getType();
9633 switch(ty)
9634 {
9635 case widgCOUNTER:
9636 ret = 10000*((SW_Counter*)widg)->infitm;
9637 break;
9638 case widgOLDCTR:
9639 ret = 10000*((SW_Counters*)widg)->infitm;
9640 break;
9641 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE:
9642 ret = 10000*((SW_GaugePiece*)widg)->inf_item;
9643 break;
9644 case widgITMCOOLDOWNGAUGE:
9645 default:
9646 bad_subwidg_type(false, ty);
9647 ret = -10000;
9648 break;
9649 }
9650 }
9651 break;
9652 }
9653 case SUBWIDGTY_INFCHAR:
9654 {
9655 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9656 {
9657 auto ty = widg->getType();
9658 switch(ty)
9659 {
9660 case widgCOUNTER:
9661 ret = 10000*byte(((SW_Counter*)widg)->infchar);
9662 break;
9663 case widgOLDCTR:
9664 ret = 10000*byte(((SW_Counters*)widg)->infchar);
9665 break;
9666 case widgBTNCOUNTER:
9667 ret = 10000*byte(((SW_BtnCounter*)widg)->infchar);
9668 break;
9669 default:
9670 bad_subwidg_type(false, ty);
9671 break;
9672 }
9673 }
9674 break;
9675 }
9676 case SUBWIDGTY_COSTIND:
9677 {
9678 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9679 {
9680 auto ty = widg->getType();
9681 switch(ty)
9682 {
9683 case widgBTNCOUNTER:
9684 ret = 10000*((SW_BtnCounter*)widg)->costind;
9685 break;
9686 default:
9687 bad_subwidg_type(false, ty);
9688 ret = -1;
9689 break;
9690 }
9691 }
9692 break;
9693 }
9694 case SUBWIDGTY_COLOR_PLAYER:
9695 {
9696 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9697 {
9698 auto ty = widg->getType();
9699 switch(ty)
9700 {
9701 case widgMMAP:
9702 ret = 10000*((SW_MMap*)widg)->c_plr.get_int_color();
9703 break;
9704 case widgLMAP:
9705 ret = 10000*((SW_LMap*)widg)->c_plr.get_int_color();
9706 break;
9707 default:
9708 bad_subwidg_type(false, ty);
9709 break;
9710 }
9711 }
9712 break;
9713 }
9714 case SUBWIDGTY_COLOR_CMPBLNK:
9715 {
9716 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9717 {
9718 auto ty = widg->getType();
9719 switch(ty)
9720 {
9721 case widgMMAP:
9722 ret = 10000*((SW_MMap*)widg)->c_cmp_blink.get_int_color();
9723 break;
9724 default:
9725 bad_subwidg_type(false, ty);
9726 break;
9727 }
9728 }
9729 break;
9730 }
9731 case SUBWIDGTY_COLOR_CMPOFF:
9732 {
9733 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9734 {
9735 auto ty = widg->getType();
9736 switch(ty)
9737 {
9738 case widgMMAP:
9739 ret = 10000*((SW_MMap*)widg)->c_cmp_off.get_int_color();
9740 break;
9741 default:
9742 bad_subwidg_type(false, ty);
9743 break;
9744 }
9745 }
9746 break;
9747 }
9748 case SUBWIDGTY_COLOR_ROOM:
9749 {
9750 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9751 {
9752 auto ty = widg->getType();
9753 switch(ty)
9754 {
9755 case widgLMAP:
9756 ret = 10000*((SW_LMap*)widg)->c_room.get_int_color();
9757 break;
9758 default:
9759 bad_subwidg_type(false, ty);
9760 break;
9761 }
9762 }
9763 break;
9764 }
9765 case SUBWIDGTY_ITEMCLASS:
9766 {
9767 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9768 {
9769 auto ty = widg->getType();
9770 switch(ty)
9771 {
9772 case widgITEMSLOT:
9773 ret = 10000*((SW_ItemSlot*)widg)->iclass;
9774 break;
9775 case widgITMCOOLDOWNGAUGE:
9776 ret = 10000*((SW_ItemCooldownGauge*)widg)->item_class;
9777 break;
9778 case widgITMCOOLDOWNTEXT:
9779 ret = 10000*((SW_ItemCooldownText*)widg)->item_class;
9780 break;
9781 default:
9782 bad_subwidg_type(false, ty);
9783 break;
9784 }
9785 }
9786 break;
9787 }
9788 case SUBWIDGTY_ITEMID:
9789 {
9790
2/4
✓ Branch 0 taken 1455 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1455 times.
1455 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9791 {
9792 1455 auto ty = widg->getType();
9793
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1455 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1455 switch(ty)
9794 {
9795 case widgITEMSLOT:
9796 1455 ret = 10000*((SW_ItemSlot*)widg)->iid;
9797 1455 break;
9798 case widgITMCOOLDOWNGAUGE:
9799 ret = 10000*((SW_ItemCooldownGauge*)widg)->specific_item_id;
9800 break;
9801 case widgITMCOOLDOWNTEXT:
9802 ret = 10000*((SW_ItemCooldownText*)widg)->specific_item_id;
9803 break;
9804 default:
9805 bad_subwidg_type(false, ty);
9806 break;
9807 }
9808 1455 }
9809 1455 break;
9810 }
9811 case SUBWIDGTY_FRAMETILE:
9812 {
9813 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9814 {
9815 auto ty = widg->getType();
9816 switch(ty)
9817 {
9818 case widgMCGUFF_FRAME:
9819 ret = 10000*((SW_TriFrame*)widg)->frame_tile;
9820 break;
9821 default:
9822 bad_subwidg_type(false, ty);
9823 break;
9824 }
9825 }
9826 break;
9827 }
9828 case SUBWIDGTY_FRAMECSET:
9829 {
9830 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9831 {
9832 auto ty = widg->getType();
9833 switch(ty)
9834 {
9835 case widgMCGUFF_FRAME:
9836 ret = 10000*((SW_TriFrame*)widg)->frame_cset;
9837 break;
9838 default:
9839 bad_subwidg_type(false, ty);
9840 break;
9841 }
9842 }
9843 break;
9844 }
9845 case SUBWIDGTY_PIECETILE:
9846 {
9847 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9848 {
9849 auto ty = widg->getType();
9850 switch(ty)
9851 {
9852 case widgMCGUFF_FRAME:
9853 ret = 10000*((SW_TriFrame*)widg)->piece_tile;
9854 break;
9855 default:
9856 bad_subwidg_type(false, ty);
9857 break;
9858 }
9859 }
9860 break;
9861 }
9862 case SUBWIDGTY_PIECECSET:
9863 {
9864 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9865 {
9866 auto ty = widg->getType();
9867 switch(ty)
9868 {
9869 case widgMCGUFF_FRAME:
9870 ret = 10000*((SW_TriFrame*)widg)->piece_cset;
9871 break;
9872 default:
9873 bad_subwidg_type(false, ty);
9874 break;
9875 }
9876 }
9877 break;
9878 }
9879 case SUBWIDGTY_FLIP:
9880 {
9881 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9882 {
9883 auto ty = widg->getType();
9884 switch(ty)
9885 {
9886 case widgMCGUFF:
9887 ret = 10000*((SW_McGuffin*)widg)->flip;
9888 break;
9889 case widgTILEBLOCK:
9890 ret = 10000*((SW_TileBlock*)widg)->flip;
9891 break;
9892 case widgMINITILE:
9893 ret = 10000*((SW_MiniTile*)widg)->flip;
9894 break;
9895 default:
9896 bad_subwidg_type(false, ty);
9897 break;
9898 }
9899 }
9900 break;
9901 }
9902 case SUBWIDGTY_NUMBER:
9903 {
9904 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9905 {
9906 auto ty = widg->getType();
9907 switch(ty)
9908 {
9909 case widgMCGUFF:
9910 ret = 10000*((SW_McGuffin*)widg)->number;
9911 break;
9912 default:
9913 bad_subwidg_type(false, ty);
9914 break;
9915 }
9916 }
9917 break;
9918 }
9919 case SUBWIDGTY_FRAMES:
9920 {
9921 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9922 {
9923 auto ty = widg->getType();
9924 switch(ty)
9925 {
9926 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
9927 ret = 10000*((SW_GaugePiece*)widg)->frames;
9928 break;
9929 default:
9930 bad_subwidg_type(false, ty);
9931 ret = -10000;
9932 break;
9933 }
9934 }
9935 break;
9936 }
9937 case SUBWIDGTY_SPEED:
9938 {
9939 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9940 {
9941 auto ty = widg->getType();
9942 switch(ty)
9943 {
9944 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
9945 ret = 10000*((SW_GaugePiece*)widg)->speed;
9946 break;
9947 default:
9948 bad_subwidg_type(false, ty);
9949 ret = -10000;
9950 break;
9951 }
9952 }
9953 break;
9954 }
9955 case SUBWIDGTY_DELAY:
9956 {
9957 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9958 {
9959 auto ty = widg->getType();
9960 switch(ty)
9961 {
9962 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
9963 ret = 10000*((SW_GaugePiece*)widg)->delay;
9964 break;
9965 default:
9966 bad_subwidg_type(false, ty);
9967 ret = -10000;
9968 break;
9969 }
9970 }
9971 break;
9972 }
9973 case SUBWIDGTY_CONTAINER:
9974 {
9975 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9976 {
9977 auto ty = widg->getType();
9978 switch(ty)
9979 {
9980 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
9981 ret = 10000*((SW_GaugePiece*)widg)->container;
9982 break;
9983 default:
9984 bad_subwidg_type(false, ty);
9985 ret = -10000;
9986 break;
9987 }
9988 }
9989 break;
9990 }
9991 case SUBWIDGTY_GAUGE_WID:
9992 {
9993 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
9994 {
9995 auto ty = widg->getType();
9996 switch(ty)
9997 {
9998 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
9999 ret = 10000*(((SW_GaugePiece*)widg)->gauge_wid+1);
10000 break;
10001 default:
10002 bad_subwidg_type(false, ty);
10003 ret = -10000;
10004 break;
10005 }
10006 }
10007 break;
10008 }
10009 case SUBWIDGTY_GAUGE_HEI:
10010 {
10011 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10012 {
10013 auto ty = widg->getType();
10014 switch(ty)
10015 {
10016 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10017 ret = 10000*(((SW_GaugePiece*)widg)->gauge_hei+1);
10018 break;
10019 default:
10020 bad_subwidg_type(false, ty);
10021 ret = -10000;
10022 break;
10023 }
10024 }
10025 break;
10026 }
10027 case SUBWIDGTY_UNITS:
10028 {
10029 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10030 {
10031 auto ty = widg->getType();
10032 switch(ty)
10033 {
10034 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10035 ret = 10000*(((SW_GaugePiece*)widg)->unit_per_frame+1);
10036 break;
10037 default:
10038 bad_subwidg_type(false, ty);
10039 ret = -10000;
10040 break;
10041 }
10042 }
10043 break;
10044 }
10045 case SUBWIDGTY_HSPACE:
10046 {
10047 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10048 {
10049 auto ty = widg->getType();
10050 switch(ty)
10051 {
10052 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10053 ret = 10000*((SW_GaugePiece*)widg)->hspace;
10054 break;
10055 default:
10056 bad_subwidg_type(false, ty);
10057 ret = -10000;
10058 break;
10059 }
10060 }
10061 break;
10062 }
10063 case SUBWIDGTY_VSPACE:
10064 {
10065 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10066 {
10067 auto ty = widg->getType();
10068 switch(ty)
10069 {
10070 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10071 ret = 10000*((SW_GaugePiece*)widg)->vspace;
10072 break;
10073 default:
10074 bad_subwidg_type(false, ty);
10075 ret = -10000;
10076 break;
10077 }
10078 }
10079 break;
10080 }
10081 case SUBWIDGTY_GRIDX:
10082 {
10083 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10084 {
10085 auto ty = widg->getType();
10086 switch(ty)
10087 {
10088 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10089 ret = 10000*((SW_GaugePiece*)widg)->grid_xoff;
10090 break;
10091 default:
10092 bad_subwidg_type(false, ty);
10093 ret = -10000;
10094 break;
10095 }
10096 }
10097 break;
10098 }
10099 case SUBWIDGTY_GRIDY:
10100 {
10101 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10102 {
10103 auto ty = widg->getType();
10104 switch(ty)
10105 {
10106 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10107 ret = 10000*((SW_GaugePiece*)widg)->grid_yoff;
10108 break;
10109 default:
10110 bad_subwidg_type(false, ty);
10111 ret = -10000;
10112 break;
10113 }
10114 }
10115 break;
10116 }
10117 case SUBWIDGTY_ANIMVAL:
10118 {
10119 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10120 {
10121 auto ty = widg->getType();
10122 switch(ty)
10123 {
10124 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
10125 ret = 10000*((SW_GaugePiece*)widg)->anim_val;
10126 break;
10127 default:
10128 bad_subwidg_type(false, ty);
10129 ret = -10000;
10130 break;
10131 }
10132 }
10133 break;
10134 }
10135 case SUBWIDGTY_SHOWDRAIN:
10136 {
10137 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10138 {
10139 auto ty = widg->getType();
10140 switch(ty)
10141 {
10142 case widgMGAUGE:
10143 ret = 10000*((SW_MagicGaugePiece*)widg)->showdrain;
10144 break;
10145 default:
10146 bad_subwidg_type(false, ty);
10147 ret = -10000;
10148 break;
10149 }
10150 }
10151 break;
10152 }
10153 case SUBWIDGTY_PERCONTAINER:
10154 {
10155 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10156 {
10157 auto ty = widg->getType();
10158 switch(ty)
10159 {
10160 case widgMISCGAUGE:
10161 ret = 10000*((SW_MiscGaugePiece*)widg)->per_container;
10162 break;
10163 case widgITMCOOLDOWNGAUGE:
10164 ret = 10000*((SW_ItemCooldownGauge*)widg)->per_container;
10165 break;
10166 default:
10167 bad_subwidg_type(false, ty);
10168 ret = -10000;
10169 break;
10170 }
10171 }
10172 break;
10173 }
10174 case SUBWIDGTY_TOTAL:
10175 {
10176 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10177 {
10178 auto ty = widg->getType();
10179 switch(ty)
10180 {
10181 case widgITMCOOLDOWNGAUGE:
10182 ret = 10000*((SW_ItemCooldownGauge*)widg)->total_points;
10183 break;
10184 default:
10185 bad_subwidg_type(false, ty);
10186 ret = -10000;
10187 break;
10188 }
10189 }
10190 break;
10191 }
10192 case SUBWIDGTY_TABSIZE:
10193 {
10194 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10195 {
10196 auto ty = widg->getType();
10197 switch(ty)
10198 {
10199 case widgTEXTBOX:
10200 ret = 10000*((SW_TextBox*)widg)->tabsize;
10201 break;
10202 case widgSELECTEDTEXT:
10203 ret = 10000*((SW_SelectedText*)widg)->tabsize;
10204 break;
10205 default:
10206 bad_subwidg_type(false, ty);
10207 ret = -10000;
10208 break;
10209 }
10210 }
10211 break;
10212 }
10213 case SUBWIDGTY_LITEMS:
10214 {
10215 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
10216 {
10217 auto ty = widg->getType();
10218 switch(ty)
10219 {
10220 case widgMMAP:
10221 ret = 10000*((SW_MMap*)widg)->compass_litems;
10222 break;
10223 default:
10224 bad_subwidg_type(false, ty);
10225 ret = -10000;
10226 break;
10227 }
10228 }
10229 break;
10230 }
10231
10232 case GETRENDERTARGET:
10233 ret=(zscriptDrawingRenderTarget->GetCurrentRenderTarget())*10000;
10234 break;
10235
10236 default:
10237 {
10238
2/2
✓ Branch 0 taken 461406821 times.
✓ Branch 1 taken 303622011 times.
765028832 if (zasm_array_supports(arg))
10239 {
10240 461406821 int ref_arg = get_register_ref_dependency(arg).value_or(0);
10241 #ifdef DEBUG_REGISTER_DEPS
10242 if (ref_arg) debug_get_ref(ref_arg);
10243 #endif
10244
2/2
✓ Branch 0 taken 273943361 times.
✓ Branch 1 taken 187463460 times.
461406821 int ref = ref_arg ? get_ref(ref_arg) : 0;
10245 461406821 ret = zasm_array_get(arg, ref, GET_D(rINDEX) / 10000);
10246 461406821 }
10247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303622011 times.
303622011 else if (auto r = scripting_engine_get_register(arg))
10248 303622011 ret = *r;
10249 765028832 break;
10250 }
10251 }
10252
10253 3241840218 current_zasm_register = 0;
10254
10255 3241840218 return ret;
10256 4570302983 }
10257
10258 //Setter Instructions
10259
10260
10261 2462424054 void set_register(int32_t arg, int32_t value)
10262 {
10263
3/4
✓ Branch 0 taken 2462424054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1817405806 times.
✓ Branch 3 taken 645018248 times.
2462424054 if (arg >= D(0) && arg <= D(7))
10264 {
10265 645018248 ri->d[arg - D(0)] = value;
10266 645018248 return;
10267 }
10268
4/4
✓ Branch 0 taken 1783353993 times.
✓ Branch 1 taken 34051813 times.
✓ Branch 2 taken 1783314706 times.
✓ Branch 3 taken 39287 times.
1817405806 else if (arg >= GD(0) && arg <= GD(MAX_SCRIPT_REGISTERS))
10269 {
10270 39287 game->global_d[arg-GD(0)] = value;
10271 39287 return;
10272 }
10273
10274 //Macros
10275
10276 #define SET_SPRITEDATA_VAR_INT(member, str) \
10277 { \
10278 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) ) \
10279 { \
10280 Z_scripterrlog("Invalid Sprite ID passed to spritedata->%s: %d\n", str, GET_REF(spritedataref)); \
10281 } \
10282 else \
10283 { \
10284 wpnsbuf[GET_REF(spritedataref)].member = vbound((value / 10000),0,214747); \
10285 } \
10286 } \
10287
10288 #define SET_SPRITEDATA_VAR_BYTE(member, str) \
10289 { \
10290 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) ) \
10291 { \
10292 Z_scripterrlog("Invalid Sprite ID passed to spritedata->%s: %d\n", str, GET_REF(spritedataref)); \
10293 } \
10294 else \
10295 { \
10296 wpnsbuf[GET_REF(spritedataref)].member = vbound((value / 10000),0,255); \
10297 } \
10298 } \
10299
10300 1817366519 current_zasm_register = arg;
10301
10302 // Do not ever use `return` in these cases!
10303
227/985
✓ Branch 0 taken 4515947 times.
✓ Branch 1 taken 13964 times.
✓ Branch 2 taken 2047856 times.
✓ Branch 3 taken 3683 times.
✓ Branch 4 taken 2299966 times.
✓ Branch 5 taken 2299128 times.
✓ Branch 6 taken 13928 times.
✓ Branch 7 taken 14206 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 14336 times.
✓ Branch 10 taken 16044 times.
✓ Branch 11 taken 4153 times.
✓ Branch 12 taken 4155 times.
✓ Branch 13 taken 13890 times.
✓ Branch 14 taken 13913 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 811 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 76581 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 2220 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 62 times.
✓ Branch 25 taken 1 times.
✓ Branch 26 taken 48 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 871 times.
✓ Branch 29 taken 2319 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 718 times.
✓ Branch 32 taken 5878 times.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 26326 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✓ Branch 48 taken 3 times.
✓ Branch 49 taken 277656 times.
✓ Branch 50 taken 878585 times.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✓ Branch 54 taken 475 times.
✓ Branch 55 taken 4859 times.
✓ Branch 56 taken 3652 times.
✓ Branch 57 taken 2578 times.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✓ Branch 66 taken 4 times.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✓ Branch 85 taken 1135896 times.
✓ Branch 86 taken 745063 times.
✓ Branch 87 taken 299968 times.
✓ Branch 88 taken 296242 times.
✓ Branch 89 taken 282832 times.
✓ Branch 90 taken 282860 times.
✓ Branch 91 taken 187242 times.
✓ Branch 92 taken 120980 times.
✓ Branch 93 taken 119032 times.
✓ Branch 94 taken 119083 times.
✓ Branch 95 taken 262942 times.
✓ Branch 96 taken 262942 times.
✓ Branch 97 taken 262942 times.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✓ Branch 102 taken 1135888 times.
✓ Branch 103 taken 745063 times.
✓ Branch 104 taken 261841 times.
✓ Branch 105 taken 261833 times.
✓ Branch 106 taken 261906 times.
✓ Branch 107 taken 261940 times.
✓ Branch 108 taken 177985 times.
✓ Branch 109 taken 112110 times.
✓ Branch 110 taken 115497 times.
✓ Branch 111 taken 115548 times.
✓ Branch 112 taken 262942 times.
✓ Branch 113 taken 262942 times.
✓ Branch 114 taken 262942 times.
✓ Branch 115 taken 262942 times.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✓ Branch 139 taken 214057 times.
✓ Branch 140 taken 30 times.
✓ Branch 141 taken 214043 times.
✓ Branch 142 taken 971 times.
✓ Branch 143 taken 408 times.
✗ Branch 144 not taken.
✓ Branch 145 taken 71609 times.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✓ Branch 148 taken 82238 times.
✓ Branch 149 taken 1939 times.
✗ Branch 150 not taken.
✓ Branch 151 taken 6 times.
✓ Branch 152 taken 6 times.
✓ Branch 153 taken 1441 times.
✗ Branch 154 not taken.
✓ Branch 155 taken 6730 times.
✓ Branch 156 taken 476 times.
✓ Branch 157 taken 148992 times.
✓ Branch 158 taken 154523 times.
✗ Branch 159 not taken.
✓ Branch 160 taken 2464 times.
✓ Branch 161 taken 3263 times.
✗ Branch 162 not taken.
✓ Branch 163 taken 26540 times.
✓ Branch 164 taken 6 times.
✓ Branch 165 taken 429 times.
✓ Branch 166 taken 6 times.
✓ Branch 167 taken 787 times.
✓ Branch 168 taken 6 times.
✓ Branch 169 taken 885 times.
✓ Branch 170 taken 839 times.
✓ Branch 171 taken 2465 times.
✓ Branch 172 taken 6 times.
✓ Branch 173 taken 71310 times.
✓ Branch 174 taken 71308 times.
✓ Branch 175 taken 1768 times.
✓ Branch 176 taken 70954 times.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✓ Branch 180 taken 6 times.
✓ Branch 181 taken 72525 times.
✓ Branch 182 taken 72542 times.
✓ Branch 183 taken 6 times.
✓ Branch 184 taken 833 times.
✓ Branch 185 taken 833 times.
✓ Branch 186 taken 25012 times.
✗ Branch 187 not taken.
✓ Branch 188 taken 42 times.
✓ Branch 189 taken 12 times.
✓ Branch 190 taken 68360 times.
✓ Branch 191 taken 1130 times.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 197 not taken.
✓ Branch 198 taken 527 times.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✓ Branch 203 taken 72192 times.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✓ Branch 212 taken 390184 times.
✓ Branch 213 taken 30 times.
✓ Branch 214 taken 390781 times.
✓ Branch 215 taken 57530 times.
✓ Branch 216 taken 55587 times.
✗ Branch 217 not taken.
✓ Branch 218 taken 227257 times.
✓ Branch 219 taken 117 times.
✗ Branch 220 not taken.
✓ Branch 221 taken 457872 times.
✓ Branch 222 taken 305561 times.
✓ Branch 223 taken 93 times.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✓ Branch 226 taken 293753 times.
✗ Branch 227 not taken.
✓ Branch 228 taken 7539 times.
✓ Branch 229 taken 12175 times.
✓ Branch 230 taken 305977 times.
✓ Branch 231 taken 398520 times.
✗ Branch 232 not taken.
✓ Branch 233 taken 74446 times.
✓ Branch 234 taken 178 times.
✗ Branch 235 not taken.
✓ Branch 236 taken 35337 times.
✗ Branch 237 not taken.
✓ Branch 238 taken 199 times.
✓ Branch 239 taken 1039 times.
✓ Branch 240 taken 199 times.
✓ Branch 241 taken 549 times.
✓ Branch 242 taken 78832 times.
✓ Branch 243 taken 156969 times.
✓ Branch 244 taken 4552 times.
✗ Branch 245 not taken.
✓ Branch 246 taken 194229 times.
✓ Branch 247 taken 193736 times.
✓ Branch 248 taken 84994 times.
✓ Branch 249 taken 44193 times.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✗ Branch 252 not taken.
✓ Branch 253 taken 325611 times.
✓ Branch 254 taken 325024 times.
✓ Branch 255 taken 44 times.
✓ Branch 256 taken 202345 times.
✓ Branch 257 taken 202345 times.
✓ Branch 258 taken 37812 times.
✗ Branch 259 not taken.
✗ Branch 260 not taken.
✗ Branch 261 not taken.
✓ Branch 262 taken 5519 times.
✗ Branch 263 not taken.
✗ Branch 264 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 267 not taken.
✓ Branch 268 taken 4 times.
✗ Branch 269 not taken.
✓ Branch 270 taken 8364 times.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✓ Branch 273 taken 91132 times.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 279 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 282 not taken.
✓ Branch 283 taken 6 times.
✓ Branch 284 taken 360 times.
✓ Branch 285 taken 360 times.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 288 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 291 not taken.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 294 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 297 not taken.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 300 not taken.
✓ Branch 301 taken 14 times.
✗ Branch 302 not taken.
✗ Branch 303 not taken.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✗ Branch 308 not taken.
✗ Branch 309 not taken.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✗ Branch 312 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 315 not taken.
✓ Branch 316 taken 30 times.
✓ Branch 317 taken 30 times.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 321 not taken.
✗ Branch 322 not taken.
✗ Branch 323 not taken.
✓ Branch 324 taken 10 times.
✗ Branch 325 not taken.
✗ Branch 326 not taken.
✗ Branch 327 not taken.
✗ Branch 328 not taken.
✗ Branch 329 not taken.
✗ Branch 330 not taken.
✗ Branch 331 not taken.
✗ Branch 332 not taken.
✗ Branch 333 not taken.
✗ Branch 334 not taken.
✗ Branch 335 not taken.
✓ Branch 336 taken 27297 times.
✓ Branch 337 taken 537 times.
✗ Branch 338 not taken.
✓ Branch 339 taken 900 times.
✓ Branch 340 taken 7396 times.
✓ Branch 341 taken 6728 times.
✗ Branch 342 not taken.
✓ Branch 343 taken 11 times.
✗ Branch 344 not taken.
✗ Branch 345 not taken.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✗ Branch 348 not taken.
✓ Branch 349 taken 606224 times.
✓ Branch 350 taken 114 times.
✗ Branch 351 not taken.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 354 not taken.
✗ Branch 355 not taken.
✗ Branch 356 not taken.
✗ Branch 357 not taken.
✗ Branch 358 not taken.
✗ Branch 359 not taken.
✗ Branch 360 not taken.
✗ Branch 361 not taken.
✗ Branch 362 not taken.
✗ Branch 363 not taken.
✗ Branch 364 not taken.
✗ Branch 365 not taken.
✗ Branch 366 not taken.
✗ Branch 367 not taken.
✗ Branch 368 not taken.
✗ Branch 369 not taken.
✗ Branch 370 not taken.
✗ Branch 371 not taken.
✗ Branch 372 not taken.
✗ Branch 373 not taken.
✗ Branch 374 not taken.
✗ Branch 375 not taken.
✗ Branch 376 not taken.
✗ Branch 377 not taken.
✗ Branch 378 not taken.
✗ Branch 379 not taken.
✗ Branch 380 not taken.
✗ Branch 381 not taken.
✗ Branch 382 not taken.
✗ Branch 383 not taken.
✗ Branch 384 not taken.
✗ Branch 385 not taken.
✗ Branch 386 not taken.
✗ Branch 387 not taken.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✗ Branch 390 not taken.
✗ Branch 391 not taken.
✗ Branch 392 not taken.
✗ Branch 393 not taken.
✗ Branch 394 not taken.
✗ Branch 395 not taken.
✗ Branch 396 not taken.
✗ Branch 397 not taken.
✗ Branch 398 not taken.
✗ Branch 399 not taken.
✗ Branch 400 not taken.
✓ Branch 401 taken 168468 times.
✗ Branch 402 not taken.
✗ Branch 403 not taken.
✗ Branch 404 not taken.
✗ Branch 405 not taken.
✗ Branch 406 not taken.
✗ Branch 407 not taken.
✗ Branch 408 not taken.
✗ Branch 409 not taken.
✓ Branch 410 taken 5120 times.
✗ Branch 411 not taken.
✗ Branch 412 not taken.
✗ Branch 413 not taken.
✗ Branch 414 not taken.
✗ Branch 415 not taken.
✗ Branch 416 not taken.
✗ Branch 417 not taken.
✗ Branch 418 not taken.
✗ Branch 419 not taken.
✓ Branch 420 taken 3450 times.
✗ Branch 421 not taken.
✗ Branch 422 not taken.
✗ Branch 423 not taken.
✗ Branch 424 not taken.
✗ Branch 425 not taken.
✗ Branch 426 not taken.
✗ Branch 427 not taken.
✗ Branch 428 not taken.
✗ Branch 429 not taken.
✗ Branch 430 not taken.
✗ Branch 431 not taken.
✗ Branch 432 not taken.
✗ Branch 433 not taken.
✗ Branch 434 not taken.
✗ Branch 435 not taken.
✗ Branch 436 not taken.
✗ Branch 437 not taken.
✗ Branch 438 not taken.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✗ Branch 441 not taken.
✗ Branch 442 not taken.
✗ Branch 443 not taken.
✗ Branch 444 not taken.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✗ Branch 447 not taken.
✗ Branch 448 not taken.
✗ Branch 449 not taken.
✗ Branch 450 not taken.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✗ Branch 453 not taken.
✗ Branch 454 not taken.
✗ Branch 455 not taken.
✗ Branch 456 not taken.
✗ Branch 457 not taken.
✗ Branch 458 not taken.
✗ Branch 459 not taken.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 462 not taken.
✗ Branch 463 not taken.
✗ Branch 464 not taken.
✗ Branch 465 not taken.
✗ Branch 466 not taken.
✗ Branch 467 not taken.
✗ Branch 468 not taken.
✗ Branch 469 not taken.
✗ Branch 470 not taken.
✗ Branch 471 not taken.
✗ Branch 472 not taken.
✗ Branch 473 not taken.
✗ Branch 474 not taken.
✗ Branch 475 not taken.
✗ Branch 476 not taken.
✗ Branch 477 not taken.
✗ Branch 478 not taken.
✗ Branch 479 not taken.
✗ Branch 480 not taken.
✗ Branch 481 not taken.
✗ Branch 482 not taken.
✗ Branch 483 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 486 not taken.
✗ Branch 487 not taken.
✗ Branch 488 not taken.
✗ Branch 489 not taken.
✗ Branch 490 not taken.
✗ Branch 491 not taken.
✗ Branch 492 not taken.
✗ Branch 493 not taken.
✗ Branch 494 not taken.
✗ Branch 495 not taken.
✗ Branch 496 not taken.
✗ Branch 497 not taken.
✗ Branch 498 not taken.
✗ Branch 499 not taken.
✗ Branch 500 not taken.
✗ Branch 501 not taken.
✗ Branch 502 not taken.
✗ Branch 503 not taken.
✗ Branch 504 not taken.
✗ Branch 505 not taken.
✗ Branch 506 not taken.
✗ Branch 507 not taken.
✗ Branch 508 not taken.
✗ Branch 509 not taken.
✗ Branch 510 not taken.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 513 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 516 not taken.
✗ Branch 517 not taken.
✗ Branch 518 not taken.
✗ Branch 519 not taken.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✗ Branch 522 not taken.
✗ Branch 523 not taken.
✗ Branch 524 not taken.
✗ Branch 525 not taken.
✗ Branch 526 not taken.
✗ Branch 527 not taken.
✗ Branch 528 not taken.
✗ Branch 529 not taken.
✗ Branch 530 not taken.
✗ Branch 531 not taken.
✗ Branch 532 not taken.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✗ Branch 538 not taken.
✗ Branch 539 not taken.
✗ Branch 540 not taken.
✗ Branch 541 not taken.
✗ Branch 542 not taken.
✗ Branch 543 not taken.
✗ Branch 544 not taken.
✗ Branch 545 not taken.
✗ Branch 546 not taken.
✗ Branch 547 not taken.
✗ Branch 548 not taken.
✗ Branch 549 not taken.
✗ Branch 550 not taken.
✗ Branch 551 not taken.
✗ Branch 552 not taken.
✗ Branch 553 not taken.
✗ Branch 554 not taken.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 558 not taken.
✗ Branch 559 not taken.
✗ Branch 560 not taken.
✗ Branch 561 not taken.
✗ Branch 562 not taken.
✗ Branch 563 not taken.
✗ Branch 564 not taken.
✗ Branch 565 not taken.
✗ Branch 566 not taken.
✗ Branch 567 not taken.
✗ Branch 568 not taken.
✗ Branch 569 not taken.
✗ Branch 570 not taken.
✗ Branch 571 not taken.
✗ Branch 572 not taken.
✗ Branch 573 not taken.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 576 not taken.
✗ Branch 577 not taken.
✗ Branch 578 not taken.
✗ Branch 579 not taken.
✗ Branch 580 not taken.
✗ Branch 581 not taken.
✗ Branch 582 not taken.
✗ Branch 583 not taken.
✗ Branch 584 not taken.
✗ Branch 585 not taken.
✗ Branch 586 not taken.
✗ Branch 587 not taken.
✗ Branch 588 not taken.
✗ Branch 589 not taken.
✗ Branch 590 not taken.
✗ Branch 591 not taken.
✗ Branch 592 not taken.
✗ Branch 593 not taken.
✗ Branch 594 not taken.
✗ Branch 595 not taken.
✗ Branch 596 not taken.
✗ Branch 597 not taken.
✗ Branch 598 not taken.
✗ Branch 599 not taken.
✗ Branch 600 not taken.
✗ Branch 601 not taken.
✗ Branch 602 not taken.
✗ Branch 603 not taken.
✗ Branch 604 not taken.
✗ Branch 605 not taken.
✗ Branch 606 not taken.
✗ Branch 607 not taken.
✗ Branch 608 not taken.
✗ Branch 609 not taken.
✗ Branch 610 not taken.
✗ Branch 611 not taken.
✗ Branch 612 not taken.
✗ Branch 613 not taken.
✗ Branch 614 not taken.
✗ Branch 615 not taken.
✗ Branch 616 not taken.
✗ Branch 617 not taken.
✗ Branch 618 not taken.
✓ Branch 619 taken 2240371 times.
✓ Branch 620 taken 59236618 times.
✓ Branch 621 taken 12785291 times.
✓ Branch 622 taken 48396677 times.
✓ Branch 623 taken 169200048 times.
✓ Branch 624 taken 109290671 times.
✓ Branch 625 taken 132051524 times.
✗ Branch 626 not taken.
✓ Branch 627 taken 12299117 times.
✗ Branch 628 not taken.
✓ Branch 629 taken 22412 times.
✓ Branch 630 taken 412757 times.
✓ Branch 631 taken 2 times.
✓ Branch 632 taken 979359 times.
✗ Branch 633 not taken.
✓ Branch 634 taken 220 times.
✓ Branch 635 taken 10 times.
✗ Branch 636 not taken.
✗ Branch 637 not taken.
✓ Branch 638 taken 10426928 times.
✓ Branch 639 taken 284 times.
✗ Branch 640 not taken.
✗ Branch 641 not taken.
✓ Branch 642 taken 109743 times.
✓ Branch 643 taken 20806 times.
✓ Branch 644 taken 103742 times.
✓ Branch 645 taken 521996 times.
✗ Branch 646 not taken.
✓ Branch 647 taken 192996 times.
✓ Branch 648 taken 1134 times.
✓ Branch 649 taken 7263 times.
✓ Branch 650 taken 137 times.
✓ Branch 651 taken 67 times.
✗ Branch 652 not taken.
✗ Branch 653 not taken.
✗ Branch 654 not taken.
✗ Branch 655 not taken.
✗ Branch 656 not taken.
✗ Branch 657 not taken.
✗ Branch 658 not taken.
✗ Branch 659 not taken.
✗ Branch 660 not taken.
✗ Branch 661 not taken.
✗ Branch 662 not taken.
✗ Branch 663 not taken.
✗ Branch 664 not taken.
✗ Branch 665 not taken.
✗ Branch 666 not taken.
✗ Branch 667 not taken.
✗ Branch 668 not taken.
✗ Branch 669 not taken.
✗ Branch 670 not taken.
✗ Branch 671 not taken.
✗ Branch 672 not taken.
✗ Branch 673 not taken.
✗ Branch 674 not taken.
✗ Branch 675 not taken.
✗ Branch 676 not taken.
✗ Branch 677 not taken.
✗ Branch 678 not taken.
✗ Branch 679 not taken.
✗ Branch 680 not taken.
✗ Branch 681 not taken.
✗ Branch 682 not taken.
✗ Branch 683 not taken.
✗ Branch 684 not taken.
✗ Branch 685 not taken.
✗ Branch 686 not taken.
✗ Branch 687 not taken.
✗ Branch 688 not taken.
✓ Branch 689 taken 531793831 times.
✗ Branch 690 not taken.
✓ Branch 691 taken 47910107 times.
✓ Branch 692 taken 477697 times.
✓ Branch 693 taken 497243 times.
✓ Branch 694 taken 2779 times.
✓ Branch 695 taken 97671 times.
✗ Branch 696 not taken.
✓ Branch 697 taken 283529 times.
✓ Branch 698 taken 14323 times.
✓ Branch 699 taken 5411 times.
✗ Branch 700 not taken.
✓ Branch 701 taken 952 times.
✗ Branch 702 not taken.
✗ Branch 703 not taken.
✗ Branch 704 not taken.
✗ Branch 705 not taken.
✓ Branch 706 taken 388698 times.
✓ Branch 707 taken 96249 times.
✓ Branch 708 taken 96251 times.
✓ Branch 709 taken 96260 times.
✓ Branch 710 taken 96267 times.
✗ Branch 711 not taken.
✗ Branch 712 not taken.
✗ Branch 713 not taken.
✗ Branch 714 not taken.
✗ Branch 715 not taken.
✓ Branch 716 taken 262942 times.
✗ Branch 717 not taken.
✗ Branch 718 not taken.
✗ Branch 719 not taken.
✗ Branch 720 not taken.
✗ Branch 721 not taken.
✗ Branch 722 not taken.
✗ Branch 723 not taken.
✗ Branch 724 not taken.
✗ Branch 725 not taken.
✗ Branch 726 not taken.
✗ Branch 727 not taken.
✓ Branch 728 taken 2 times.
✗ Branch 729 not taken.
✗ Branch 730 not taken.
✗ Branch 731 not taken.
✗ Branch 732 not taken.
✗ Branch 733 not taken.
✗ Branch 734 not taken.
✗ Branch 735 not taken.
✗ Branch 736 not taken.
✗ Branch 737 not taken.
✗ Branch 738 not taken.
✗ Branch 739 not taken.
✗ Branch 740 not taken.
✗ Branch 741 not taken.
✗ Branch 742 not taken.
✗ Branch 743 not taken.
✗ Branch 744 not taken.
✗ Branch 745 not taken.
✗ Branch 746 not taken.
✗ Branch 747 not taken.
✗ Branch 748 not taken.
✗ Branch 749 not taken.
✗ Branch 750 not taken.
✗ Branch 751 not taken.
✗ Branch 752 not taken.
✗ Branch 753 not taken.
✗ Branch 754 not taken.
✗ Branch 755 not taken.
✓ Branch 756 taken 182 times.
✗ Branch 757 not taken.
✗ Branch 758 not taken.
✗ Branch 759 not taken.
✗ Branch 760 not taken.
✗ Branch 761 not taken.
✗ Branch 762 not taken.
✗ Branch 763 not taken.
✓ Branch 764 taken 2760 times.
✗ Branch 765 not taken.
✗ Branch 766 not taken.
✗ Branch 767 not taken.
✗ Branch 768 not taken.
✗ Branch 769 not taken.
✗ Branch 770 not taken.
✗ Branch 771 not taken.
✗ Branch 772 not taken.
✗ Branch 773 not taken.
✗ Branch 774 not taken.
✓ Branch 775 taken 99 times.
✗ Branch 776 not taken.
✓ Branch 777 taken 13 times.
✗ Branch 778 not taken.
✗ Branch 779 not taken.
✗ Branch 780 not taken.
✗ Branch 781 not taken.
✗ Branch 782 not taken.
✓ Branch 783 taken 4922 times.
✗ Branch 784 not taken.
✓ Branch 785 taken 1104 times.
✗ Branch 786 not taken.
✓ Branch 787 taken 4 times.
✗ Branch 788 not taken.
✗ Branch 789 not taken.
✗ Branch 790 not taken.
✗ Branch 791 not taken.
✗ Branch 792 not taken.
✓ Branch 793 taken 1853535 times.
✗ Branch 794 not taken.
✗ Branch 795 not taken.
✗ Branch 796 not taken.
✗ Branch 797 not taken.
✗ Branch 798 not taken.
✗ Branch 799 not taken.
✗ Branch 800 not taken.
✓ Branch 801 taken 370 times.
✗ Branch 802 not taken.
✓ Branch 803 taken 9 times.
✗ Branch 804 not taken.
✗ Branch 805 not taken.
✗ Branch 806 not taken.
✗ Branch 807 not taken.
✗ Branch 808 not taken.
✗ Branch 809 not taken.
✓ Branch 810 taken 42 times.
✗ Branch 811 not taken.
✗ Branch 812 not taken.
✗ Branch 813 not taken.
✗ Branch 814 not taken.
✓ Branch 815 taken 36 times.
✓ Branch 816 taken 36 times.
✗ Branch 817 not taken.
✗ Branch 818 not taken.
✓ Branch 819 taken 36 times.
✗ Branch 820 not taken.
✗ Branch 821 not taken.
✗ Branch 822 not taken.
✗ Branch 823 not taken.
✗ Branch 824 not taken.
✗ Branch 825 not taken.
✗ Branch 826 not taken.
✗ Branch 827 not taken.
✗ Branch 828 not taken.
✗ Branch 829 not taken.
✗ Branch 830 not taken.
✓ Branch 831 taken 9 times.
✗ Branch 832 not taken.
✗ Branch 833 not taken.
✗ Branch 834 not taken.
✗ Branch 835 not taken.
✗ Branch 836 not taken.
✗ Branch 837 not taken.
✗ Branch 838 not taken.
✗ Branch 839 not taken.
✗ Branch 840 not taken.
✗ Branch 841 not taken.
✗ Branch 842 not taken.
✗ Branch 843 not taken.
✗ Branch 844 not taken.
✗ Branch 845 not taken.
✗ Branch 846 not taken.
✗ Branch 847 not taken.
✗ Branch 848 not taken.
✗ Branch 849 not taken.
✗ Branch 850 not taken.
✗ Branch 851 not taken.
✗ Branch 852 not taken.
✗ Branch 853 not taken.
✗ Branch 854 not taken.
✗ Branch 855 not taken.
✗ Branch 856 not taken.
✗ Branch 857 not taken.
✗ Branch 858 not taken.
✗ Branch 859 not taken.
✗ Branch 860 not taken.
✗ Branch 861 not taken.
✗ Branch 862 not taken.
✗ Branch 863 not taken.
✗ Branch 864 not taken.
✗ Branch 865 not taken.
✗ Branch 866 not taken.
✗ Branch 867 not taken.
✗ Branch 868 not taken.
✗ Branch 869 not taken.
✗ Branch 870 not taken.
✗ Branch 871 not taken.
✗ Branch 872 not taken.
✗ Branch 873 not taken.
✗ Branch 874 not taken.
✗ Branch 875 not taken.
✗ Branch 876 not taken.
✗ Branch 877 not taken.
✗ Branch 878 not taken.
✗ Branch 879 not taken.
✗ Branch 880 not taken.
✗ Branch 881 not taken.
✗ Branch 882 not taken.
✗ Branch 883 not taken.
✗ Branch 884 not taken.
✗ Branch 885 not taken.
✗ Branch 886 not taken.
✗ Branch 887 not taken.
✗ Branch 888 not taken.
✗ Branch 889 not taken.
✗ Branch 890 not taken.
✗ Branch 891 not taken.
✗ Branch 892 not taken.
✗ Branch 893 not taken.
✗ Branch 894 not taken.
✗ Branch 895 not taken.
✓ Branch 896 taken 646378123 times.
✗ Branch 897 not taken.
✗ Branch 898 not taken.
✓ Branch 899 taken 3 times.
✗ Branch 900 not taken.
✗ Branch 901 not taken.
✗ Branch 902 not taken.
✗ Branch 903 not taken.
✗ Branch 904 not taken.
✗ Branch 905 not taken.
✗ Branch 906 not taken.
✗ Branch 907 not taken.
✗ Branch 908 not taken.
✗ Branch 909 not taken.
✗ Branch 910 not taken.
✓ Branch 911 taken 11 times.
✓ Branch 912 taken 11 times.
✓ Branch 913 taken 11 times.
✓ Branch 914 taken 11 times.
✗ Branch 915 not taken.
✗ Branch 916 not taken.
✓ Branch 917 taken 132 times.
✓ Branch 918 taken 4247 times.
✗ Branch 919 not taken.
✗ Branch 920 not taken.
✗ Branch 921 not taken.
✗ Branch 922 not taken.
✗ Branch 923 not taken.
✗ Branch 924 not taken.
✗ Branch 925 not taken.
✗ Branch 926 not taken.
✗ Branch 927 not taken.
✗ Branch 928 not taken.
✗ Branch 929 not taken.
✗ Branch 930 not taken.
✗ Branch 931 not taken.
✗ Branch 932 not taken.
✗ Branch 933 not taken.
✗ Branch 934 not taken.
✗ Branch 935 not taken.
✗ Branch 936 not taken.
✗ Branch 937 not taken.
✗ Branch 938 not taken.
✗ Branch 939 not taken.
✗ Branch 940 not taken.
✗ Branch 941 not taken.
✗ Branch 942 not taken.
✗ Branch 943 not taken.
✗ Branch 944 not taken.
✗ Branch 945 not taken.
✗ Branch 946 not taken.
✗ Branch 947 not taken.
✗ Branch 948 not taken.
✗ Branch 949 not taken.
✗ Branch 950 not taken.
✗ Branch 951 not taken.
✗ Branch 952 not taken.
✗ Branch 953 not taken.
✗ Branch 954 not taken.
✗ Branch 955 not taken.
✗ Branch 956 not taken.
✗ Branch 957 not taken.
✗ Branch 958 not taken.
✗ Branch 959 not taken.
✗ Branch 960 not taken.
✗ Branch 961 not taken.
✗ Branch 962 not taken.
✗ Branch 963 not taken.
✗ Branch 964 not taken.
✗ Branch 965 not taken.
✗ Branch 966 not taken.
✗ Branch 967 not taken.
✗ Branch 968 not taken.
✗ Branch 969 not taken.
✗ Branch 970 not taken.
✗ Branch 971 not taken.
✗ Branch 972 not taken.
✗ Branch 973 not taken.
✗ Branch 974 not taken.
✗ Branch 975 not taken.
✗ Branch 976 not taken.
✗ Branch 977 not taken.
✗ Branch 978 not taken.
✗ Branch 979 not taken.
✗ Branch 980 not taken.
✗ Branch 981 not taken.
✗ Branch 982 not taken.
✗ Branch 983 not taken.
✗ Branch 984 not taken.
1817366519 switch(arg)
10304 {
10305 ///----------------------------------------------------------------------------------------------------//
10306 //FFC Variables
10307 case DATA:
10308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4515947 times.
4515947 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10309 {
10310 4515947 zc_ffc_set(*ffc, vbound(value/10000,0,MAXCOMBOS-1));
10311 4515947 }
10312 4515947 break;
10313
10314 case FFSCRIPT:
10315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13964 times.
13964 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10316 {
10317 13964 ffc->script = vbound(value/10000, 0, NUMSCRIPTFFC-1);
10318
2/2
✓ Branch 0 taken 223424 times.
✓ Branch 1 taken 13964 times.
237388 for(int32_t i=0; i<16; i++)
10319 223424 ffc->miscellaneous[i] = 0;
10320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13964 times.
13964 if (get_qr(qr_CLEARINITDONSCRIPTCHANGE))
10321 {
10322
2/2
✓ Branch 0 taken 111712 times.
✓ Branch 1 taken 13964 times.
125676 for(int32_t i=0; i<8; i++)
10323 111712 ffc->initd[i] = 0;
10324 13964 }
10325 13964 on_reassign_script_engine_data(ScriptType::FFC, ffc->index);
10326 13964 }
10327 13964 break;
10328
10329
10330 case FCSET:
10331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2047856 times.
2047856 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10332 2047856 ffc->cset = (value/10000)&15;
10333 2047856 break;
10334
10335 case DELAY:
10336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3683 times.
3683 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10337 3683 ffc->delay = value/10000;
10338 3683 break;
10339
10340 case FX:
10341
1/2
✓ Branch 0 taken 2299966 times.
✗ Branch 1 not taken.
2299966 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10342 2299966 ffc->x = zslongToFix(value);
10343 2299966 break;
10344
10345 case FY:
10346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2299128 times.
2299128 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10347 2299128 ffc->y=zslongToFix(value);
10348 2299128 break;
10349
10350 case XD:
10351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13928 times.
13928 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10352 13928 ffc->vx=zslongToFix(value);
10353 13928 break;
10354
10355 case YD:
10356
1/2
✓ Branch 0 taken 14206 times.
✗ Branch 1 not taken.
14206 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10357 14206 ffc->vy=zslongToFix(value);
10358 14206 break;
10359
10360 case FFCID:
10361 break;
10362
10363 case XD2:
10364
1/2
✓ Branch 0 taken 14336 times.
✗ Branch 1 not taken.
14336 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10365 14336 ffc->ax=zslongToFix(value);
10366 14336 break;
10367
10368 case YD2:
10369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16044 times.
16044 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10370 16044 ffc->ay=zslongToFix(value);
10371 16044 break;
10372
10373 case FFCWIDTH:
10374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4153 times.
4153 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10375 4153 ffc->hit_width = (value/10000);
10376 4153 break;
10377
10378 case FFCHEIGHT:
10379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4155 times.
4155 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10380 4155 ffc->hit_height = (value/10000);
10381 4155 break;
10382
10383 case FFTWIDTH:
10384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13890 times.
13890 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10385 13890 ffc->txsz = vbound(value/10000, 1, 4);
10386 13890 break;
10387
10388 case FFTHEIGHT:
10389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13913 times.
13913 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10390 13913 ffc->tysz = vbound(value/10000, 1, 4);
10391 13913 break;
10392
10393 case FFCLAYER:
10394 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10395 ffc->layer = vbound(value/10000, 0, 7);
10396 break;
10397
10398 case FFLINK:
10399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 811 times.
811 if (auto ffc = ResolveFFC(GET_REF(ffcref)))
10400 811 (ffc->link)=vbound(value/10000, 0, MAXFFCS-1); // Allow "ffc->Link = 0" to unlink ffc.
10401 //0 is none, setting this before made it impssible to clear it. -Z
10402 811 break;
10403
10404 case FFCLASTCHANGERX:
10405 if (auto ffc = ResolveFFC(GET_REF(ffcref)) )
10406 ffc->changer_x=vbound(zslongToFix(value).getInt(),-32768, 32767);
10407 break;
10408
10409 case FFCLASTCHANGERY:
10410 if (auto ffc = ResolveFFC(GET_REF(ffcref)) )
10411 ffc->changer_y=vbound(zslongToFix(value).getInt(),-32768, 32767);
10412 break;
10413
10414
10415
10416 ///----------------------------------------------------------------------------------------------------//
10417 //Hero's Variables
10418 case LINKX:
10419 {
10420
2/2
✓ Branch 0 taken 23258 times.
✓ Branch 1 taken 454439 times.
477697 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
10421 {
10422 23258 Hero.setXfix(zslongToFix(value));
10423 23258 }
10424 else
10425 {
10426 454439 Hero.setX(value/10000);
10427 }
10428 }
10429 477697 break;
10430
10431 case LINKCSET:
10432 {
10433 Hero.cs = value/10000;
10434 break;
10435 }
10436 case LINKY:
10437 {
10438
2/2
✓ Branch 0 taken 22483 times.
✓ Branch 1 taken 474760 times.
497243 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
10439 {
10440 22483 Hero.setYfix(zslongToFix(value));
10441 22483 }
10442 else
10443 {
10444 474760 Hero.setY(value/10000);
10445 }
10446 }
10447 497243 break;
10448
10449 case LINKZ:
10450 {
10451
2/2
✓ Branch 0 taken 2775 times.
✓ Branch 1 taken 4 times.
2779 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
10452 {
10453 2775 Hero.setZfix(zslongToFix(value));
10454 2775 }
10455 else
10456 {
10457 4 Hero.setZ(value/10000);
10458 }
10459 }
10460 2779 break;
10461
10462 case LINKJUMP:
10463 76581 Hero.setJump(zslongToFix(value));
10464 76581 break;
10465
10466 case HEROFAKEJUMP:
10467 Hero.setFakeFall(zslongToFix(value) * -100);
10468 break;
10469
10470 case LINKDIR:
10471 {
10472 //Hero->setDir() calls reset_hookshot(), which removes the sword sprite.. O_o
10473
3/4
✓ Branch 0 taken 95485 times.
✓ Branch 1 taken 2186 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 95485 times.
97671 if(Hero.getAction() == attacking || Hero.getAction() == sideswimattacking) Hero.dir = (value/10000);
10474 95485 else Hero.setDir(value/10000);
10475
10476 97671 break;
10477 }
10478
10479 case LINKHITDIR:
10480 2220 Hero.setHitDir(value / 10000);
10481 2220 break;
10482
10483 case LINKGRAVITY:
10484 if(value)
10485 Hero.moveflags |= move_obeys_grav;
10486 else
10487 Hero.moveflags &= ~move_obeys_grav;
10488 break;
10489
10490 case HERONOSTEPFORWARD:
10491 FFCore.nostepforward = ( (value) ? 1 : 0 );
10492 break;
10493
10494 case LINKHP:
10495
6/6
✓ Branch 0 taken 177824 times.
✓ Branch 1 taken 105705 times.
✓ Branch 2 taken 283358 times.
✓ Branch 3 taken 171 times.
✓ Branch 4 taken 177653 times.
✓ Branch 5 taken 105705 times.
283529 game->set_life(zc_max(0, zc_min(value/10000,game->get_maxlife())));
10496 283529 break;
10497
10498 case LINKMP:
10499
6/6
✓ Branch 0 taken 6606 times.
✓ Branch 1 taken 7717 times.
✓ Branch 2 taken 14302 times.
✓ Branch 3 taken 21 times.
✓ Branch 4 taken 6585 times.
✓ Branch 5 taken 7717 times.
14323 game->set_magic(zc_max(0, zc_min(value/10000,game->get_maxmagic())));
10500 14323 break;
10501
10502 case LINKMAXHP:
10503 62 game->set_maxlife(value/10000);
10504 62 break;
10505
10506 case LINKMAXMP:
10507 1 game->set_maxmagic(value/10000);
10508 1 break;
10509
10510 case LINKACTION:
10511 {
10512 5411 int32_t act = value / 10000;
10513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5411 times.
5411 switch(act)
10514 {
10515 case hookshotout:
10516 case stunned:
10517 case ispushing:
10518 FFCore.setHeroAction(act);
10519 break;
10520 default:
10521 5411 Hero.setAction((actiontype)(act));
10522 5411 }
10523 //Protect from writing illegal actions to Hero's raw variable.
10524 //in the future, we can move all scripted actions that are not possible
10525 //to set in ZC into this mechanic. -Z
10526 5411 break;
10527 }
10528
10529 case HEROHEALTHBEEP:
10530 {
10531 int32_t beep = vbound((value/10000),-4, 255);
10532 //-2 suspends system control of stopping the sound
10533 //-3 suspends system control of stopping the sound AND suspends
10534 // system control over starting or playing it.
10535 heart_beep_timer = beep;
10536 if ( heart_beep_timer > -1 )
10537 {
10538 cont_sfx(QMisc.miscsfx[sfxLOWHEART]);
10539 }
10540 else
10541 {
10542 stop_sfx(QMisc.miscsfx[sfxLOWHEART]);
10543 }
10544 break;
10545 }
10546
10547 case LINKHELD:
10548 48 Hero.setHeldItem(vbound(value/10000,0,MAXITEMS-1));
10549 48 break;
10550
10551 case HEROSTEPRATE:
10552
1/2
✓ Branch 0 taken 952 times.
✗ Branch 1 not taken.
952 if(!get_qr(qr_NEW_HERO_MOVEMENT))
10553 {
10554 Z_scripterrlog("To use '%s', you must %s the quest rule '%s'.", "Hero->Step", "enable", "New Hero Movement");
10555 }
10556
1/2
✓ Branch 0 taken 952 times.
✗ Branch 1 not taken.
952 Hero.setStepRate(zc_max(value/10000,0));
10557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 952 times.
952 if(!get_qr(qr_SCRIPT_WRITING_HEROSTEP_DOESNT_CARRY_OVER))
10558 952 zinit.heroStep = Hero.getStepRate();
10559 952 break;
10560 case HEROSHOVEOFFSET:
10561 if(!get_qr(qr_NEW_HERO_MOVEMENT2))
10562 Z_scripterrlog("To use 'Hero->ShoveOffset', you must enable the quest rule 'Newer Hero Movement'.");
10563 Hero.shove_offset = vbound(zslongToFix(value),16_zf,0_zf);
10564 if(!get_qr(qr_SCRIPT_WRITING_HEROSTEP_DOESNT_CARRY_OVER))
10565 zinit.shove_offset = Hero.shove_offset;
10566 break;
10567
10568 case LINKEQUIP:
10569 {
10570 if ( FFCore.getQuestHeaderInfo(vZelda) == 0x250 && FFCore.getQuestHeaderInfo(vBuild) < 33 )
10571 {
10572 break;
10573 }
10574 //int32_t seta = (value/10000) >> 8; int32_t setb = value/10000) & 0xFF;
10575 int32_t setb = ((value/10000)&0xFF00)>>8, seta = (value/10000)&0xFF;
10576 seta = vbound(seta,-1,255);
10577 setb = vbound(setb,-1,255);
10578
10579 Awpn = seta;
10580 game->awpn = 255;
10581 game->forced_awpn = seta;
10582 game->items_off[seta] = 0;
10583 directItemA = seta;
10584
10585 Bwpn = setb;
10586 game->bwpn = 255;
10587 game->forced_bwpn = setb;
10588 game->items_off[setb] = 0;
10589 directItemB = setb;
10590 break;
10591 }
10592
10593
10594 case SETITEMSLOT:
10595 {
10596 //value = third arg
10597 //int32_t item, int32_t slot, int32_t force
10598 int32_t itm = GET_D(rINDEX)/10000;
10599 itm = vbound(itm, -1, 255);
10600
10601 int32_t slot = GET_D(rINDEX2)/10000;
10602 int32_t force = GET_D(rEXP1)/10000;
10603
10604 //If we add more item buttons, slot should be an int32_t
10605 //and force shuld be an int32_t
10606
10607 /*
10608 For zScript,
10609 const int32_t ITM_REQUIRE_NONE = 0
10610 const int32_t ITM_REQUIRE_INVENTORY = 1
10611 const int32_t ITM_REQUIRE_A_SLOT_RULE = 2
10612 //Combine as flags
10613 */
10614 if ( force == 0 )
10615 {
10616 switch(slot)
10617 {
10618 case 0: //b
10619 Bwpn = itm;
10620 game->items_off[itm] = 0;
10621 game->bwpn = 255;
10622 game->forced_bwpn = itm;
10623 directItemB = itm;
10624 break;
10625
10626 case 1: //a
10627 Awpn = itm;
10628 game->items_off[itm] = 0;
10629 game->awpn = 255;
10630 game->forced_awpn = itm;
10631 directItemA = itm;
10632 break;
10633
10634 case 2: //x
10635 Xwpn = itm;
10636 game->items_off[itm] = 0;
10637 game->xwpn = 255;
10638 game->forced_xwpn = itm;
10639 directItemX = itm;
10640 break;
10641
10642 case 3: //y
10643 Ywpn = itm;
10644 game->items_off[itm] = 0;
10645 game->ywpn = 255;
10646 game->forced_ywpn = itm;
10647 directItemX = itm;
10648 break;
10649 }
10650 }
10651 else if ( force == 1 )
10652 {
10653 if (game->item[itm])
10654 {
10655 switch(slot)
10656 {
10657 case 0: //b
10658 Bwpn = itm;
10659 game->items_off[itm] = 0;
10660 game->bwpn = 255;
10661 game->forced_bwpn = itm;
10662 directItemB = itm;
10663 break;
10664
10665 case 1: //a
10666 Awpn = itm;
10667 game->items_off[itm] = 0;
10668 game->awpn = 255;
10669 game->forced_awpn = itm;
10670 directItemA = itm;
10671 break;
10672
10673 case 2: //x
10674 Xwpn = itm;
10675 game->items_off[itm] = 0;
10676 game->xwpn = 255;
10677 game->forced_xwpn = itm;
10678 directItemX = itm;
10679 break;
10680
10681 case 3: //y
10682 Ywpn = itm;
10683 game->items_off[itm] = 0;
10684 game->ywpn = 255;
10685 game->forced_ywpn = itm;
10686 directItemY = itm;
10687 break;
10688 }
10689 }
10690 }
10691 else if ( force == 2 )
10692 {
10693 switch(slot)
10694 {
10695 case 0: //b
10696 Bwpn = itm;
10697 game->items_off[itm] = 0;
10698 game->bwpn = 255;
10699 game->forced_bwpn = itm;
10700 directItemB = itm;
10701 break;
10702
10703 case 1: //a
10704 if (get_qr(qr_SELECTAWPN))
10705 {
10706 Awpn = itm;
10707 game->items_off[itm] = 0;
10708 game->awpn = 255;
10709 game->forced_awpn = itm;
10710 directItemA = itm;
10711 }
10712 break;
10713
10714 case 2: //x
10715 Xwpn = itm;
10716 game->items_off[itm] = 0;
10717 game->xwpn = 255;
10718 game->forced_xwpn = itm;
10719 directItemX = itm;
10720 break;
10721
10722 case 3: //y
10723 Ywpn = itm;
10724 game->items_off[itm] = 0;
10725 game->ywpn = 255;
10726 game->forced_ywpn = itm;
10727 directItemY = itm;
10728 break;
10729 }
10730 }
10731 else if ( force == 3 ) //Flag ITM_REQUIRE_INVENTORY + ITM_REQUIRE_SLOT_A_RULE
10732 {
10733 if ( game->item[itm] )
10734 {
10735 switch(slot)
10736 {
10737 case 0: //b
10738 Bwpn = itm;
10739 game->items_off[itm] = 0;
10740 game->bwpn = 255;
10741 game->forced_bwpn = itm;
10742 directItemB = itm;
10743 break;
10744
10745 case 1: //a
10746 if (get_qr(qr_SELECTAWPN))
10747 {
10748 Awpn = itm;
10749 game->items_off[itm] = 0;
10750 game->awpn = 255;
10751 game->forced_awpn = itm;
10752 directItemA = itm;
10753 }
10754 break;
10755
10756 case 2: //x
10757 Xwpn = itm;
10758 game->items_off[itm] = 0;
10759 game->xwpn = 255;
10760 game->forced_xwpn = itm;
10761 directItemX = itm;
10762 break;
10763
10764 case 3: //y
10765 Ywpn = itm;
10766 game->items_off[itm] = 0;
10767 game->ywpn = 255;
10768 game->forced_ywpn = itm;
10769 directItemY = itm;
10770 break;
10771 }
10772 }
10773 }
10774 }
10775 break;
10776
10777 case LINKINVIS:
10778 871 Hero.setDontDraw((value ? 2 : 0));
10779 871 break;
10780
10781 case LINKINVINC:
10782 2319 Hero.scriptcoldet=(value/10000);
10783 2319 break;
10784
10785 case LINKENGINEANIMATE:
10786 Hero.do_animation=value;
10787 break;
10788
10789 case LINKSWORDJINX:
10790 718 Hero.setSwordClk(value/10000);
10791 718 break;
10792
10793 case LINKITEMJINX:
10794 5878 Hero.setItemClk(value/10000);
10795 5878 break;
10796
10797 case LINKDRUNK:
10798 1 Hero.setDrunkClock(value/10000);
10799 1 break;
10800
10801 case LINKHXOFS:
10802 (Hero.hxofs)=(zfix)(value/10000);
10803 break;
10804
10805 case LINKROTATION:
10806 if ( get_qr(qr_OLDSPRITEDRAWS) )
10807 {
10808 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
10809 break;
10810 }
10811 (Hero.rotation)=(value/10000);
10812 break;
10813
10814 case LINKSCALE:
10815 {
10816 if ( get_qr(qr_OLDSPRITEDRAWS) )
10817 {
10818 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
10819 break;
10820 }
10821 (Hero.scale)=(value/100.0);
10822 break;
10823 }
10824
10825 case LINKHYOFS:
10826 (Hero.hyofs)=(zfix)(value/10000);
10827 break;
10828
10829 case LINKXOFS:
10830 26326 (Hero.xofs)=(zfix)(value/10000);
10831 26326 break;
10832
10833 case LINKYOFS:
10834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 388698 times.
388698 (Hero.yofs)=(zfix)(value/10000)+(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
10835 388698 break;
10836 case HEROTOTALDYOFFS:
10837 break; //READ-ONLY
10838
10839 case HEROSHADOWXOFS:
10840 (Hero.shadowxofs)=(zfix)(value/10000);
10841 break;
10842
10843 case HEROSHADOWYOFS:
10844 (Hero.shadowyofs)=(zfix)(value/10000);
10845 break;
10846
10847 case LINKZOFS:
10848 (Hero.zofs)=(zfix)(value/10000);
10849 break;
10850
10851 case LINKHXSZ:
10852 (Hero.hit_width)=(zfix)(value/10000);
10853 break;
10854
10855 case LINKHYSZ:
10856 (Hero.hit_height)=(zfix)(value/10000);
10857 break;
10858
10859 case LINKHZSZ:
10860 (Hero.hzsz)=(zfix)(value/10000);
10861 break;
10862
10863 case LINKTXSZ:
10864 (Hero.txsz)=(zfix)(value/10000);
10865 break;
10866
10867 case LINKTYSZ:
10868 (Hero.tysz)=(zfix)(value/10000);
10869 break;
10870
10871 case LINKTILE:
10872 (Hero.tile)=(zfix)(value/10000);
10873 break;
10874
10875 case LINKFLIP:
10876 (Hero.flip)=(zfix)(value/10000);
10877 break;
10878
10879
10880
10881 case LINKINVFRAME:
10882 3 Hero.setHClk( (int32_t)vbound((value/10000), 0, 214747) );
10883 3 break;
10884
10885 case LINKCANFLICKER:
10886 277656 Hero.setCanFlicker((value/10000)?1:0);
10887 277656 break;
10888
10889 case LINKHURTSFX:
10890 878585 Hero.setHurtSFX( (int32_t)vbound((value/10000), 0, 255) );
10891 878585 break;
10892
10893
10894 case LINKITEMB:
10895 {
10896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96249 times.
96249 if ( value/10000 < -1 )
10897 {
10898 al_trace("Tried to write an invalid item ID to Hero->ItemB: %d\n",value/10000);
10899 break;
10900 }
10901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96249 times.
96249 if ( value/10000 > MAXITEMS-1 )
10902 {
10903 al_trace("Tried to write an invalid item ID to Hero->ItemB: %d\n",value/10000);
10904 break;
10905 }
10906 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
10907
10908
2/2
✓ Branch 0 taken 96237 times.
✓ Branch 1 taken 12 times.
96249 if (Bwpn != (value/10000))
10909 {
10910 12 Bwpn = value/10000;
10911
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(new_subscreen_active)
10912 12 new_subscreen_active->get_page_pos(Bwpn, game->bwpn);
10913 12 game->forced_bwpn = value/10000;
10914 12 game->items_off[value/10000] = 0;
10915 12 }
10916 96249 directItemB = value/10000;
10917 96249 break;
10918 }
10919
10920
10921 case LINKITEMA:
10922 {
10923
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96251 times.
96251 if ( value/10000 < -1 )
10924 {
10925 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemA: %d\n",value/10000);
10926 break;
10927 }
10928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96251 times.
96251 if ( value/10000 > MAXITEMS-1 )
10929 {
10930 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemA: %d\n",value/10000);
10931 break;
10932 }
10933 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
10934
2/2
✓ Branch 0 taken 96240 times.
✓ Branch 1 taken 11 times.
96251 if (Awpn != (value/10000))
10935 {
10936 11 Awpn = value/10000;
10937
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if(new_subscreen_active)
10938 11 new_subscreen_active->get_page_pos(Awpn, game->awpn);
10939 11 game->items_off[value/10000] = 0;
10940 11 game->forced_awpn = value/10000;
10941 11 }
10942 96251 directItemA = value/10000;
10943 96251 break;
10944 }
10945
10946 case LINKITEMX:
10947 {
10948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96260 times.
96260 if ( value/10000 < -1 )
10949 {
10950 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemX: %d\n",value/10000);
10951 break;
10952 }
10953
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96260 times.
96260 if ( value/10000 > MAXITEMS-1 )
10954 {
10955 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemX: %d\n",value/10000);
10956 break;
10957 }
10958 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
10959
2/2
✓ Branch 0 taken 96226 times.
✓ Branch 1 taken 34 times.
96260 if (Xwpn != (value/10000))
10960 {
10961 34 Xwpn = value/10000;
10962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if(new_subscreen_active)
10963 34 new_subscreen_active->get_page_pos(Xwpn, game->xwpn);
10964 34 game->items_off[value/10000] = 0;
10965 34 game->forced_xwpn = value/10000;
10966 34 }
10967 96260 directItemX = value/10000;
10968 96260 break;
10969 }
10970 case LINKITEMY:
10971 {
10972
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96267 times.
96267 if ( value/10000 < -1 )
10973 {
10974 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemY: %d\n",value/10000);
10975 break;
10976 }
10977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96267 times.
96267 if ( value/10000 > MAXITEMS-1 )
10978 {
10979 Z_scripterrlog("Tried to write an invalid item ID to Hero->ItemY: %d\n",value/10000);
10980 break;
10981 }
10982 //Hero->setBButtonItem(vbound((value/10000),0,(MAXITEMS-1)));
10983
2/2
✓ Branch 0 taken 96222 times.
✓ Branch 1 taken 45 times.
96267 if (Ywpn != (value/10000))
10984 {
10985 45 Ywpn = value/10000;
10986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 if(new_subscreen_active)
10987 45 new_subscreen_active->get_page_pos(Ywpn, game->ywpn);
10988 45 game->items_off[value/10000] = 0;
10989 45 game->forced_ywpn = value/10000;
10990 45 }
10991 96267 directItemY = value/10000;
10992 96267 break;
10993 }
10994
10995
10996 case LINKEATEN:
10997 Hero.setEaten(value/10000);
10998 break;
10999 case LINKGRABBED:
11000 Hero.inwallm = value != 0;
11001 break;
11002 case HEROBUNNY:
11003 Hero.setBunnyClock(value/10000);
11004 break;
11005 case LINKPUSH:
11006 Hero.pushing = zc_max((value/10000),0);
11007 break;
11008 case LINKSTUN:
11009 475 Hero.setStunClock(value/10000);
11010 475 break;
11011 case LINKSCRIPTTILE:
11012 4859 script_hero_sprite=vbound((value/10000), -1, NEWMAXTILES-1);
11013 4859 break;
11014
11015 case HEROSCRIPTCSET:
11016 3652 script_hero_cset=vbound((value/10000), -1, 0xF);
11017 3652 break;
11018 case LINKSCRIPFLIP:
11019 2578 script_hero_flip=vbound((value/10000),-1,256);
11020 2578 break;
11021
11022 //Set Hero Diagonal
11023 case LINKDIAG:
11024 Hero.setDiagMove(value?1:0);
11025 set_qr(qr_LTTPWALK, value?1:0);
11026 break;
11027
11028 //Set Hero Big Hitbox
11029 case LINKBIGHITBOX:
11030 Hero.setBigHitbox((value/10000)?1:0);
11031 set_qr(qr_LTTPCOLLISION, (value/10000)?1:0);
11032 break;
11033
11034 case LINKCLIMBING:
11035 Hero.setOnSideviewLadder(value!=0?true:false);
11036 break;
11037
11038 case HEROJUMPCOUNT:
11039 Hero.extra_jump_count = value/10000;
11040 break;
11041
11042 case HEROPULLCLK:
11043 Hero.pit_pullclk = value/10000;
11044 break;
11045 case HEROFALLCLK:
11046 {
11047 int32_t val = vbound(value/10000,0,70);
11048 if(val)
11049 Hero.setAction(falling);
11050 else if(Hero.action == falling)
11051 {
11052 Hero.setAction(none);
11053 }
11054 Hero.fallclk = val;
11055 break;
11056 }
11057 case HEROFALLCMB:
11058 Hero.fallCombo = vbound(value/10000,0,MAXCOMBOS-1);
11059 break;
11060 case HERODROWNCLK:
11061 {
11062 int32_t val = vbound(value/10000,0,70);
11063 if(val)
11064 {
11065 if (Hero.action != lavadrowning) Hero.setAction(drowning);
11066 }
11067 else if(Hero.action == drowning || Hero.action == lavadrowning)
11068 {
11069 Hero.setAction(none);
11070 }
11071 Hero.drownclk = val;
11072 break;
11073 }
11074 case HERODROWNCMB:
11075 Hero.drownCombo = vbound(value/10000,0,MAXCOMBOS-1);
11076 break;
11077 case HEROFAKEZ:
11078 {
11079 if ( get_qr(qr_SPRITEXY_IS_FLOAT) )
11080 {
11081 Hero.setFakeZfix(zslongToFix(value));
11082 }
11083 else
11084 {
11085 Hero.setFakeZ(value/10000);
11086 }
11087 }
11088 break;
11089
11090 case HEROSHIELDJINX:
11091 {
11092 Hero.shieldjinxclk = value / 10000;
11093 break;
11094 }
11095
11096 case CLOCKACTIVE:
11097 {
11098 4 Hero.setClock(watch=(value?true:false));
11099 4 break;
11100 }
11101
11102 case CLOCKCLK:
11103 clockclk = vbound((value/10000), 0, 214748);
11104 break;
11105
11106 case HERORESPAWNX:
11107 {
11108 zfix zx = zslongToFix(value);
11109 Hero.respawn_x = vbound(zx, 0_zf, 240_zf);
11110 break;
11111 }
11112
11113 case HERORESPAWNY:
11114 {
11115 zfix zy = zslongToFix(value);
11116 Hero.respawn_y = vbound(zy, 0_zf, 160_zf);
11117 break;
11118 }
11119
11120 case HERORESPAWNDMAP:
11121 {
11122 Hero.respawn_dmap = vbound(value/10000, 0, MAXDMAPS-1);
11123 break;
11124 }
11125
11126 case HERORESPAWNSCR:
11127 {
11128 Hero.respawn_scr = vbound(value/10000, 0, 0x7F);
11129 break;
11130 }
11131
11132
11133 case HEROSWITCHMAXTIMER:
11134 case HEROSWITCHTIMER:
11135 break; //read-only
11136
11137 case HEROIMMORTAL:
11138 {
11139 Hero.setImmortal(value/10000);
11140 break;
11141 }
11142
11143 case HEROCOYOTETIME:
11144 {
11145 auto v = value/10000;
11146 if(v < 0 || v > 65535) v = 65535;
11147 Hero.coyotetime = word(v);
11148 break;
11149 }
11150 case HEROLIFTEDWPN:
11151 {
11152 if(Hero.lift_wpn)
11153 {
11154 delete Hero.lift_wpn;
11155 Hero.lift_wpn = nullptr;
11156 }
11157 if(value)
11158 {
11159 if(weapon* wpn = checkLWpn(value))
11160 {
11161 if(wpn == Hero.lift_wpn) break;
11162 Hero.lift_wpn = wpn;
11163 if(Lwpns.find(wpn) > -1)
11164 Lwpns.remove(wpn);
11165 if(curScriptType == ScriptType::Lwpn && value == curScriptIndex)
11166 earlyretval = RUNSCRIPT_SELFREMOVE;
11167 }
11168 }
11169 break;
11170 }
11171 case HEROLIFTTIMER:
11172 {
11173 Hero.liftclk = value/10000;
11174 break;
11175 }
11176 case HEROLIFTMAXTIMER:
11177 {
11178 Hero.tliftclk = value/10000;
11179 break;
11180 }
11181 case HEROLIFTHEIGHT:
11182 {
11183 Hero.liftheight = zslongToFix(value);
11184 break;
11185 }
11186 case HEROHAMMERSTATE:
11187 {
11188 //readonly
11189 break;
11190 }
11191 case HEROFLICKERCOLOR:
11192 {
11193 Hero.flickercolor = value/10000;
11194 break;
11195 }
11196 case HEROFLICKERTRANSP:
11197 {
11198 Hero.flickertransp = value / 10000;
11199 break;
11200 }
11201 case HEROSCRICECMB:
11202 Hero.script_ice_combo = vbound(value/10000,-1,MAXCOMBOS); break;
11203 case HEROICEVX:
11204 Hero.ice_vx = zslongToFix(value); break;
11205 case HEROICEVY:
11206 Hero.ice_vy = zslongToFix(value); break;
11207 case HEROICEENTRYFRAMES:
11208 Hero.ice_entry_count = vbound(value/10000,0,255); break;
11209 case HEROICEENTRYMAXFRAMES:
11210 Hero.ice_entry_mcount = vbound(value/10000,0,255); break;
11211
11212
11213 ///----------------------------------------------------------------------------------------------------//
11214 //Input States
11215 case INPUTSTART:
11216 {
11217 1135896 control_state[6]=(value?true:false);
11218
2/2
✓ Branch 0 taken 1058724 times.
✓ Branch 1 taken 77172 times.
1135896 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[6]=false;
11219 1135896 break;
11220 }
11221
11222 case INPUTMAP:
11223 {
11224 745063 control_state[9]=(value?true:false);
11225
2/2
✓ Branch 0 taken 476961 times.
✓ Branch 1 taken 268102 times.
745063 if ( get_qr(qr_FIXDRUNKINPUTS) )
11226 268102 drunk_toggle_state[9]=false;
11227 745063 break;
11228 }
11229
11230 case INPUTUP:
11231 {
11232 299968 control_state[0]=(value?true:false);
11233
2/2
✓ Branch 0 taken 293445 times.
✓ Branch 1 taken 6523 times.
299968 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[0]=false;
11234 299968 break;
11235 }
11236
11237 case INPUTDOWN:
11238 {
11239 296242 control_state[1]=(value?true:false);
11240
2/2
✓ Branch 0 taken 290748 times.
✓ Branch 1 taken 5494 times.
296242 if ( get_qr(qr_FIXDRUNKINPUTS) )
11241 5494 drunk_toggle_state[1]=false;
11242 296242 break;
11243 }
11244
11245 case INPUTLEFT:
11246 {
11247 282832 control_state[2]=(value?true:false);
11248
2/2
✓ Branch 0 taken 277104 times.
✓ Branch 1 taken 5728 times.
282832 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[2]=false;
11249 282832 break;
11250 }
11251
11252 case INPUTRIGHT:
11253 {
11254 282860 control_state[3]=(value?true:false);
11255
2/2
✓ Branch 0 taken 277163 times.
✓ Branch 1 taken 5697 times.
282860 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[3]=false;
11256 282860 break;
11257 }
11258
11259 case INPUTA:
11260 {
11261 187242 control_state[4]=(value?true:false);
11262
2/2
✓ Branch 0 taken 142947 times.
✓ Branch 1 taken 44295 times.
187242 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[4]=false;
11263 187242 break;
11264 }
11265
11266 case INPUTB:
11267 {
11268 120980 control_state[5]=(value?true:false);
11269
2/2
✓ Branch 0 taken 116814 times.
✓ Branch 1 taken 4166 times.
120980 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[5]=false;
11270 120980 break;
11271 }
11272
11273 case INPUTL:
11274 {
11275 119032 control_state[7]=(value?true:false);
11276
2/2
✓ Branch 0 taken 116528 times.
✓ Branch 1 taken 2504 times.
119032 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[7]=false;
11277 119032 break;
11278 }
11279
11280 case INPUTR:
11281 {
11282 119083 control_state[8]=(value?true:false);
11283
2/2
✓ Branch 0 taken 116579 times.
✓ Branch 1 taken 2504 times.
119083 if ( get_qr(qr_FIXDRUNKINPUTS) ) drunk_toggle_state[8]=false;
11284 119083 break;
11285 }
11286
11287 case INPUTEX1:
11288 {
11289 262942 control_state[10]=(value?true:false);
11290 262942 break;
11291 }
11292
11293 case INPUTEX2:
11294 262942 control_state[11]=(value?true:false);
11295 262942 break;
11296
11297 case INPUTEX3:
11298 262942 control_state[12]=(value?true:false);
11299 262942 break;
11300
11301 case INPUTEX4:
11302 262942 control_state[13]=(value?true:false);
11303 262942 break;
11304
11305 case INPUTAXISUP:
11306 control_state[14]=(value?true:false);
11307 break;
11308
11309 case INPUTAXISDOWN:
11310 control_state[15]=(value?true:false);
11311 break;
11312
11313 case INPUTAXISLEFT:
11314 control_state[16]=(value?true:false);
11315 break;
11316
11317 case INPUTAXISRIGHT:
11318 control_state[17]=(value?true:false);
11319 break;
11320
11321 case INPUTPRESSSTART:
11322 1135888 button_press[6]=(value?true:false);
11323 1135888 break;
11324
11325 case INPUTPRESSMAP:
11326 745063 button_press[9]=(value?true:false);
11327 745063 break;
11328
11329 case INPUTPRESSUP:
11330 261841 button_press[0]=(value?true:false);
11331 261841 break;
11332
11333 case INPUTPRESSDOWN:
11334 261833 button_press[1]=(value?true:false);
11335 261833 break;
11336
11337 case INPUTPRESSLEFT:
11338 261906 button_press[2]=(value?true:false);
11339 261906 break;
11340
11341 case INPUTPRESSRIGHT:
11342 261940 button_press[3]=(value?true:false);
11343 261940 break;
11344
11345 case INPUTPRESSA:
11346 177985 button_press[4]=(value?true:false);
11347 177985 break;
11348
11349 case INPUTPRESSB:
11350 112110 button_press[5]=(value?true:false);
11351 112110 break;
11352
11353 case INPUTPRESSL:
11354 115497 button_press[7]=(value?true:false);
11355 115497 break;
11356
11357 case INPUTPRESSR:
11358 115548 button_press[8]=(value?true:false);
11359 115548 break;
11360
11361 case INPUTPRESSEX1:
11362 262942 button_press[10]=(value?true:false);
11363 262942 break;
11364
11365 case INPUTPRESSEX2:
11366 262942 button_press[11]=(value?true:false);
11367 262942 break;
11368
11369 case INPUTPRESSEX3:
11370 262942 button_press[12]=(value?true:false);
11371 262942 break;
11372
11373 case INPUTPRESSEX4:
11374 262942 button_press[13]=(value?true:false);
11375 262942 break;
11376
11377 case PRESSAXISUP:
11378 button_press[14]=(value?true:false);
11379 break;
11380
11381 case PRESSAXISDOWN:
11382 button_press[15]=(value?true:false);
11383 break;
11384
11385 case PRESSAXISLEFT:
11386 button_press[16]=(value?true:false);
11387 break;
11388
11389 case PRESSAXISRIGHT:
11390 button_press[17]=(value?true:false);
11391 break;
11392
11393 case INPUTMOUSEX:
11394 {
11395 auto [x, y] = rti_game.local_to_world(value/10000, mouse_y);
11396 position_mouse(x, y);
11397 break;
11398 }
11399
11400 case INPUTMOUSEY:
11401 {
11402 int32_t mousequakeoffset = 56+((int32_t)(zc::math::Sin((double)(quakeclk*int64_t(2)-frame))*4));
11403 int32_t tempoffset = (quakeclk > 0) ? mousequakeoffset : (get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
11404 auto [x, y] = rti_game.local_to_world(mouse_x, value/10000 + tempoffset);
11405 position_mouse(x, y);
11406 break;
11407 }
11408
11409 case INPUTMOUSEZ:
11410 position_mouse_z(value/10000);
11411 break;
11412
11413 case SIMULATEKEYPRESS:
11414 {
11415 //if ( !keypressed() ) break; //Don;t return values set by setting Hero->Input/Press
11416 //hmm...no, this won;t return properly for modifier keys.
11417 int32_t keyid = GET_D(rINDEX)/10000;
11418 //key = vbound(key,0,n);
11419 if (value/10000) simulate_keypress(keyid << 8);
11420 }
11421 break;
11422
11423 case KEYMODIFIERS:
11424 {
11425 key_shifts = ( value/10000 );
11426 break;
11427 }
11428 break;
11429
11430 ///----------------------------------------------------------------------------------------------------//
11431 //Itemdata Variables
11432 //not mine, but let;s guard some of them all the same -Z
11433 //item class
11434 case IDATATYPE:
11435 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11436 {
11437 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11438 break;
11439 }
11440 (itemsbuf[GET_REF(itemdataref)].type)=vbound(value/10000,0, 254);
11441 flushItemCache();
11442 break;
11443
11444 case IDATAUSEWPN:
11445 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11446 {
11447 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11448 break;
11449 }
11450 (itemsbuf[GET_REF(itemdataref)].weap_data.imitate_weapon)=vbound(value/10000, 0, 255);
11451 break;
11452 case IDATAUSEDEF:
11453 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11454 {
11455 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11456 break;
11457 }
11458 (itemsbuf[GET_REF(itemdataref)].weap_data.default_defense)=vbound(value/10000, 0, 255);
11459 break;
11460 case IDATAWRANGE:
11461 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11462 {
11463 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11464 break;
11465 }
11466 (itemsbuf[GET_REF(itemdataref)].weaprange)=vbound(value/10000, 0, 255);
11467 break;
11468 case IDATAMAGICTIMER:
11469 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11470 {
11471 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11472 break;
11473 }
11474 (itemsbuf[GET_REF(itemdataref)].magiccosttimer[0])=vbound(value/10000, 0, 214747);
11475 break;
11476 case IDATAMAGICTIMER2:
11477 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11478 {
11479 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11480 break;
11481 }
11482 (itemsbuf[GET_REF(itemdataref)].magiccosttimer[1])=vbound(value/10000, 0, 214747);
11483 break;
11484 case IDATADURATION:
11485 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11486 {
11487 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11488 break;
11489 }
11490 (itemsbuf[GET_REF(itemdataref)].weapduration)=vbound(value/10000, 0, 255);
11491 break;
11492
11493 case IDATADUPLICATES:
11494 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11495 {
11496 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11497 break;
11498 }
11499 (itemsbuf[GET_REF(itemdataref)].duplicates)=vbound(value/10000, 0, 255);
11500 break;
11501 case IDATADRAWLAYER:
11502 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11503 {
11504 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11505 break;
11506 }
11507 (itemsbuf[GET_REF(itemdataref)].drawlayer)=vbound(value/10000, 0, 7);
11508 break;
11509 case IDATACOLLECTFLAGS:
11510 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11511 {
11512 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11513 break;
11514 }
11515 //int32_t a = GET_D(rINDEX) / 10000;
11516 (itemsbuf[GET_REF(itemdataref)].collectflags)=vbound(value/10000, 0, 214747);
11517 break;
11518 case IDATAWEAPONSCRIPT:
11519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11520 {
11521 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11522 break;
11523 }
11524 2 (itemsbuf[GET_REF(itemdataref)].weap_data.script)=vbound(value/10000, 0, 255);
11525 2 break;
11526 case IDATAWEAPHXOFS:
11527 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11528 {
11529 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11530 break;
11531 }
11532 (itemsbuf[GET_REF(itemdataref)].weap_data.hxofs)=(value/10000);
11533 break;
11534 case IDATAWEAPHYOFS:
11535 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11536 {
11537 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11538 break;
11539 }
11540 (itemsbuf[GET_REF(itemdataref)].weap_data.hyofs)=(value/10000);
11541 break;
11542 case IDATAWEAPHXSZ:
11543 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11544 {
11545 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11546 break;
11547 }
11548 (itemsbuf[GET_REF(itemdataref)].weap_data.hxsz)=(value/10000);
11549 break;
11550 case IDATAWEAPHYSZ:
11551 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11552 {
11553 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11554 break;
11555 }
11556 (itemsbuf[GET_REF(itemdataref)].weap_data.hysz)=(value/10000);
11557 break;
11558 case IDATAWEAPHZSZ:
11559 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11560 {
11561 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11562 break;
11563 }
11564 (itemsbuf[GET_REF(itemdataref)].weap_data.hzsz)=(value/10000);
11565 break;
11566 case IDATAWEAPXOFS:
11567 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11568 {
11569 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11570 break;
11571 }
11572 (itemsbuf[GET_REF(itemdataref)].weap_data.xofs)=(value/10000);
11573 break;
11574 case IDATAWEAPYOFS:
11575 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11576 {
11577 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11578 break;
11579 }
11580 (itemsbuf[GET_REF(itemdataref)].weap_data.yofs)=(value/10000);
11581 break;
11582
11583
11584 case IDATAHXOFS:
11585 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11586 {
11587 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11588 break;
11589 }
11590 (itemsbuf[GET_REF(itemdataref)].hxofs)=(value/10000);
11591 break;
11592 case IDATAHYOFS:
11593 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11594 {
11595 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11596 break;
11597 }
11598 (itemsbuf[GET_REF(itemdataref)].hyofs)=(value/10000);
11599 break;
11600 case IDATAHXSZ:
11601 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11602 {
11603 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11604 break;
11605 }
11606 (itemsbuf[GET_REF(itemdataref)].hxsz)=(value/10000);
11607 break;
11608 case IDATAHYSZ:
11609 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11610 {
11611 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11612 break;
11613 }
11614 (itemsbuf[GET_REF(itemdataref)].hysz)=(value/10000);
11615 break;
11616 case IDATAHZSZ:
11617 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11618 {
11619 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11620 break;
11621 }
11622 (itemsbuf[GET_REF(itemdataref)].hzsz)=(value/10000);
11623 break;
11624 case IDATADXOFS:
11625 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11626 {
11627 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11628 break;
11629 }
11630 (itemsbuf[GET_REF(itemdataref)].xofs)=(value/10000);
11631 break;
11632 case IDATADYOFS:
11633 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11634 {
11635 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11636 break;
11637 }
11638 (itemsbuf[GET_REF(itemdataref)].yofs)=(value/10000);
11639 break;
11640 case IDATATILEW:
11641 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11642 {
11643 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11644 break;
11645 }
11646 (itemsbuf[GET_REF(itemdataref)].tilew)=(value/10000);
11647 break;
11648 case IDATATILEH:
11649 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11650 {
11651 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11652 break;
11653 }
11654 (itemsbuf[GET_REF(itemdataref)].tileh)=(value/10000);
11655 break;
11656 case IDATAPICKUP:
11657 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11658 {
11659 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11660 break;
11661 }
11662 (itemsbuf[GET_REF(itemdataref)].pickup)=(value/10000);
11663 break;
11664 case IDATAOVERRIDEFL:
11665 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11666 {
11667 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11668 break;
11669 }
11670 (itemsbuf[GET_REF(itemdataref)].overrideFLAGS)=(value/10000);
11671 break;
11672
11673 case IDATATILEWWEAP:
11674 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11675 {
11676 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11677 break;
11678 }
11679 (itemsbuf[GET_REF(itemdataref)].weap_data.tilew)=(value/10000);
11680 break;
11681 case IDATATILEHWEAP:
11682 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11683 {
11684 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11685 break;
11686 }
11687 (itemsbuf[GET_REF(itemdataref)].weap_data.tileh)=(value/10000);
11688 break;
11689 case IDATAOVERRIDEFLWEAP:
11690 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11691 {
11692 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11693 break;
11694 }
11695 (itemsbuf[GET_REF(itemdataref)].weap_data.override_flags)=(value/10000);
11696 break;
11697
11698 case IDATALEVEL:
11699 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11700 {
11701 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11702 break;
11703 }
11704 (itemsbuf[GET_REF(itemdataref)].level)=vbound(value/10000, 0, 512);
11705 flushItemCache();
11706 break;
11707 case IDATAKEEP:
11708 item_flag(item_gamedata, value);
11709 break;
11710 case IDATAAMOUNT:
11711 {
11712 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11713 {
11714 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11715 break;
11716 }
11717 int32_t v = vbound(value/10000, -9999, 16383);
11718 itemsbuf[GET_REF(itemdataref)].amount &= 0x8000;
11719 itemsbuf[GET_REF(itemdataref)].amount |= (abs(v)&0x3FFF)|(v<0?0x4000:0);
11720 break;
11721 }
11722 case IDATAGRADUAL:
11723 {
11724 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11725 {
11726 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11727 break;
11728 }
11729 SETFLAG(itemsbuf[GET_REF(itemdataref)].amount, 0x8000, value!=0);
11730 break;
11731 }
11732 case IDATACONSTSCRIPT:
11733 item_flag(item_passive_script, value);
11734 break;
11735 case IDATASSWIMDISABLED:
11736 item_flag(item_sideswim_disabled, value);
11737 break;
11738 case IDATABUNNYABLE:
11739 item_flag(item_bunny_enabled, value);
11740 break;
11741 case IDATAJINXIMMUNE:
11742 item_flag(item_jinx_immune, value);
11743 break;
11744 case IDATAJINXSWAP:
11745 item_flag(item_flip_jinx, value);
11746 break;
11747 case IDATAUSEBURNSPR:
11748 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11749 {
11750 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11751 }
11752 else SETFLAG(itemsbuf[GET_REF(itemdataref)].weap_data.wflags, WFLAG_UPDATE_IGNITE_SPRITE, value);
11753 break;
11754 case IDATASETMAX:
11755 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11756 {
11757 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11758 break;
11759 }
11760 (itemsbuf[GET_REF(itemdataref)].setmax)=value/10000;
11761 break;
11762
11763 case IDATAMAX:
11764 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11765 {
11766 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11767 break;
11768 }
11769 (itemsbuf[GET_REF(itemdataref)].max)=value/10000;
11770 break;
11771
11772 case IDATAPOWER:
11773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 182 times.
182 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11774 {
11775 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11776 break;
11777 }
11778 182 (itemsbuf[GET_REF(itemdataref)].power)=value/10000;
11779 182 break;
11780
11781 case IDATACOUNTER:
11782 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11783 {
11784 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11785 break;
11786 }
11787 (itemsbuf[GET_REF(itemdataref)].count)=vbound(value/10000,0,31);
11788 break;
11789
11790 case IDATAPSOUND:
11791 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11792 {
11793 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11794 break;
11795 }
11796 (itemsbuf[GET_REF(itemdataref)].playsound)=vbound(value/10000, 0, 255);
11797 break;
11798
11799 case IDATAUSESOUND:
11800 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11801 {
11802 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11803 break;
11804 }
11805 (itemsbuf[GET_REF(itemdataref)].usesound)=vbound(value/10000, 0, 255);
11806 break;
11807
11808 case IDATAUSESOUND2:
11809 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11810 {
11811 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11812 break;
11813 }
11814 (itemsbuf[GET_REF(itemdataref)].usesound2)=vbound(value/10000, 0, 255);
11815 break;
11816
11817 //2.54
11818 //My additions begin here. -Z
11819 //Stack item to gain next level
11820 case IDATACOMBINE:
11821 item_flag(item_combine, value);
11822 break;
11823 //using a level of an item downgrades to a lower one
11824 case IDATADOWNGRADE:
11825 item_flag(item_downgrade, value);
11826 break;
11827 //Only validate the cost, don't charge it
11828 case IDATAVALIDATE:
11829 item_flag(item_validate_only, value);
11830 break;
11831 case IDATAVALIDATE2:
11832 item_flag(item_validate_only_2, value);
11833 break;
11834
11835
11836 //Keep Old in editor
11837 case IDATAKEEPOLD:
11838 item_flag(item_keep_old, value);
11839 break;
11840 //Ruppes for magic
11841 case IDATARUPEECOST:
11842 item_flag(item_rupee_magic, value);
11843 break;
11844 //can be eaten
11845 case IDATAEDIBLE:
11846 item_flag(item_edible, value);
11847 break;
11848 //Unused at this time
11849 case IDATAFLAGUNUSED:
11850 item_flag(item_unused, value);
11851 break;
11852 //gain lower level items
11853 case IDATAGAINLOWER:
11854 item_flag(item_gain_old, value);
11855 break;
11856 //Set the action script
11857 case IDATASCRIPT:
11858 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11859 {
11860 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11861 break;
11862 }
11863 FFScript::deallocateAllScriptOwned(ScriptType::Item, ri->itemdataref);
11864 itemsbuf[GET_REF(itemdataref)].script=vbound(value/10000,0,255);
11865 break;
11866 case IDATASPRSCRIPT:
11867 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11868 {
11869 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11870 break;
11871 }
11872 itemsbuf[GET_REF(itemdataref)].sprite_script=vbound(value/10000,0,255);
11873 break;
11874
11875 //Hero tile modifier.
11876 case IDATALTM:
11877 {
11878 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11879 {
11880 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11881 break;
11882 }
11883 auto new_value = value/10000;
11884 if (new_value != itemsbuf[GET_REF(itemdataref)].ltm)
11885 cache_tile_mod_clear();
11886 itemsbuf[GET_REF(itemdataref)].ltm = new_value;
11887 break;
11888 }
11889 //Pickup script
11890 case IDATAPSCRIPT:
11891 {
11892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2760 times.
2760 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11893 {
11894 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11895 break;
11896 }
11897 //Need to get collect script ref, not standard idata ref!
11898
1/2
✓ Branch 0 taken 2760 times.
✗ Branch 1 not taken.
2760 const int32_t new_ref = ri->itemdataref!=0 ? -(GET_REF(itemdataref)) : COLLECT_SCRIPT_ITEM_ZERO;
11899 2760 FFScript::deallocateAllScriptOwned(ScriptType::Item,new_ref);
11900 2760 itemsbuf[GET_REF(itemdataref)].collect_script=vbound(value/10000, 0, 255);
11901 2760 break;
11902 }
11903 //pickup string
11904 case IDATAPSTRING:
11905 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11906 {
11907 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11908 break;
11909 }
11910 itemsbuf[GET_REF(itemdataref)].pstring=vbound(value/10000, 1, 255);
11911 break;
11912 case IDATAPFLAGS:
11913 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11914 {
11915 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11916 break;
11917 }
11918 itemsbuf[GET_REF(itemdataref)].pickup_string_flags=vbound(value/10000, 0, 214748);
11919 break;
11920 case IDATAPICKUPLITEMS:
11921 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11922 {
11923 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11924 break;
11925 }
11926 itemsbuf[GET_REF(itemdataref)].pickup_litems = vbound(value/10000, 0, 214748) & LI_ALL;
11927 break;
11928 case IDATAPICKUPLITEMLEVEL:
11929 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11930 {
11931 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11932 break;
11933 }
11934 itemsbuf[GET_REF(itemdataref)].pickup_litem_level = vbound(value/10000, -1, MAXLEVELS-1);
11935 break;
11936 //magic cost
11937 case IDATAMAGCOST:
11938 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11939 {
11940 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11941 break;
11942 }
11943 itemsbuf[GET_REF(itemdataref)].cost_amount[0]=vbound(value/10000,32767,-32768);
11944 break;
11945 case IDATACOST2:
11946 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11947 {
11948 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11949 break;
11950 }
11951 itemsbuf[GET_REF(itemdataref)].cost_amount[1]=vbound(value/10000,32767,-32768);
11952 break;
11953 case IDATACOOLDOWN:
11954 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11955 {
11956 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11957 break;
11958 }
11959 itemsbuf[GET_REF(itemdataref)].cooldown = zc_max(value/10000,0);
11960 break;
11961 //cost counter ref
11962 case IDATACOSTCOUNTER:
11963 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11964 {
11965 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11966 break;
11967 }
11968 itemsbuf[GET_REF(itemdataref)].cost_counter[0]=(vbound(value/10000,-1,32));
11969 break;
11970 case IDATACOSTCOUNTER2:
11971 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11972 {
11973 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11974 break;
11975 }
11976 itemsbuf[GET_REF(itemdataref)].cost_counter[1]=(vbound(value/10000,-1,32));
11977 break;
11978 //min hearts to pick up
11979 case IDATAMINHEARTS:
11980 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11981 {
11982 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11983 break;
11984 }
11985 itemsbuf[GET_REF(itemdataref)].pickup_hearts=vbound(value/10000, 0, 214748);
11986 break;
11987 //item tile
11988 case IDATATILE:
11989
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 99 times.
99 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11990 {
11991 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
11992 break;
11993 }
11994 99 itemsbuf[GET_REF(itemdataref)].tile=vbound(value/10000, 0, NEWMAXTILES-1);
11995 99 break;
11996 //flash
11997 case IDATAMISC:
11998 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
11999 {
12000 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12001 break;
12002 }
12003 itemsbuf[GET_REF(itemdataref)].misc_flags=value/10000;
12004 break;
12005 //cset
12006 case IDATACSET:
12007
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12008 {
12009 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12010 break;
12011 }
12012
12013 13 itemsbuf[GET_REF(itemdataref)].csets = (itemsbuf[GET_REF(itemdataref)].csets & 0xF0) | vbound(value/10000,0,15);
12014
12015 // If we find quests that broke, use this code.
12016 // if (QHeader.compareVer(2, 55, 9) >= 0)
12017 // itemsbuf[ri->idata].csets = (itemsbuf[ri->idata].csets & 0xF0) | vbound(value/10000,0,15);
12018 // else
12019 // itemsbuf[ri->idata].csets = vbound(value/10000,0,13);
12020 13 break;
12021
12022 case IDATAFLASHCSET:
12023 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12024 {
12025 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12026 break;
12027 }
12028
12029 itemsbuf[ri->itemdataref].csets = (itemsbuf[ri->itemdataref].csets & 0xF) | (vbound(value/10000,0,15)<<4);
12030 break;
12031 /*
12032 case IDATAFRAME:
12033 itemsbuf[ri->idata].frame=value/10000;
12034 break;
12035 */
12036 //A.Frames
12037 case IDATAFRAMES:
12038 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12039 {
12040 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12041 break;
12042 }
12043 (itemsbuf[GET_REF(itemdataref)].frames)=vbound(value/10000, 0, 214748);
12044 break;
12045 //A.speed
12046 case IDATAASPEED:
12047 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12048 {
12049 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12050 break;
12051 }
12052 itemsbuf[GET_REF(itemdataref)].speed=vbound(value/10000, 0, 214748);
12053 break;
12054 //Anim delay
12055 case IDATADELAY:
12056 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
12057 {
12058 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
12059 break;
12060 }
12061 itemsbuf[GET_REF(itemdataref)].delay=vbound(value/10000, 0, 214748);
12062 break;
12063
12064 ///----------------------------------------------------------------------------------------------------//
12065 //LWeapon Variables
12066
12067 case LWPNSCALE:
12068 if ( get_qr(qr_OLDSPRITEDRAWS) )
12069 {
12070 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
12071 break;
12072 }
12073 if(auto s=checkLWpn(GET_REF(lwpnref)))
12074 s->scale=(zfix)(value/100.0);
12075
12076 break;
12077
12078 case LWPNX:
12079
2/2
✓ Branch 0 taken 6717 times.
✓ Branch 1 taken 207340 times.
214057 if(auto s=checkLWpn(GET_REF(lwpnref)))
12080
2/2
✓ Branch 0 taken 67473 times.
✓ Branch 1 taken 139867 times.
207340 s->x=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12081 214057 break;
12082
12083 case SPRITEMAXLWPN:
12084 {
12085 //No bounds check, as this is a universal function and works from NULL pointers!
12086 30 Lwpns.setMax(vbound((value/10000),1,MAX_LWPN_SPRITES));
12087 30 break;
12088 }
12089
12090 case LWPNY:
12091
2/2
✓ Branch 0 taken 6717 times.
✓ Branch 1 taken 207326 times.
214043 if(auto s=checkLWpn(GET_REF(lwpnref)))
12092
2/2
✓ Branch 0 taken 67466 times.
✓ Branch 1 taken 139860 times.
207326 s->y=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12093
12094 214043 break;
12095
12096 case LWPNZ:
12097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 971 times.
971 if(auto s=checkLWpn(GET_REF(lwpnref)))
12098 {
12099
2/2
✓ Branch 0 taken 965 times.
✓ Branch 1 taken 6 times.
971 s->z=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12100
1/2
✓ Branch 0 taken 971 times.
✗ Branch 1 not taken.
971 if(s->z < 0) s->z = 0_zf;
12101 971 }
12102
12103 971 break;
12104
12105 case LWPNJUMP:
12106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 408 times.
408 if(auto s=checkLWpn(GET_REF(lwpnref)))
12107 408 s->fall=zslongToFix(value)*-100;
12108
12109 408 break;
12110
12111 case LWPNFAKEJUMP:
12112 if(auto s=checkLWpn(GET_REF(lwpnref)))
12113 s->fakefall=zslongToFix(value)*-100;
12114
12115 break;
12116
12117 case LWPNDIR:
12118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71609 times.
71609 if(auto s=checkLWpn(GET_REF(lwpnref)))
12119 {
12120 71609 s->dir=(value/10000);
12121 71609 s->doAutoRotate(true);
12122 71609 }
12123
12124 71609 break;
12125
12126 case LWPNSPECIAL:
12127 if(auto s=checkLWpn(GET_REF(lwpnref)))
12128 s->specialinfo=(value/10000);
12129
12130 break;
12131
12132 case LWPNGRAVITY:
12133 if(auto s=checkLWpn(GET_REF(lwpnref)))
12134 {
12135 if(value)
12136 s->moveflags |= move_obeys_grav;
12137 else
12138 s->moveflags &= ~move_obeys_grav;
12139 }
12140 break;
12141
12142 case LWPNSTEP:
12143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82238 times.
82238 if(auto s=checkLWpn(GET_REF(lwpnref)))
12144 {
12145 // fp math is bad for replay, so always ignore this QR when replay is active.
12146 // TODO: can we just delete this QR? Would it actually break anything? For now,
12147 // just disable for replay and wait for more tests to be played with this QR
12148 // ignored.
12149
3/4
✓ Branch 0 taken 7619 times.
✓ Branch 1 taken 74619 times.
✓ Branch 2 taken 7619 times.
✗ Branch 3 not taken.
82238 if ( get_qr(qr_STEP_IS_FLOAT) || replay_is_active() )
12150 {
12151 82238 s->step= zslongToFix(value / 100);
12152 82238 }
12153 else
12154 {
12155 //old, buggy code replication, round two: Go! -Z
12156 //zfix val = zslongToFix(value);
12157 //val.doFloor();
12158 //s->step = ((val / 100.0).getFloat());
12159
12160 //old, buggy code replication, round THREE: Go! -Z
12161 s->step = ((value/10000)/100.0);
12162 }
12163
12164 82238 }
12165
12166 82238 break;
12167
12168 case LWPNANGLE:
12169
1/2
✓ Branch 0 taken 1939 times.
✗ Branch 1 not taken.
1939 if(auto s=checkLWpn(GET_REF(lwpnref)))
12170 {
12171 1939 s->angle=(double)(value/10000.0);
12172 1939 s->doAutoRotate();
12173 1939 }
12174
12175 1939 break;
12176
12177 case LWPNDEGANGLE:
12178 if(auto s=checkLWpn(GET_REF(lwpnref)))
12179 {
12180 double rangle = (value / 10000.0) * (PI / 180.0);
12181 s->angle=(double)(rangle);
12182 s->doAutoRotate();
12183 }
12184
12185 break;
12186
12187 case LWPNVX:
12188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12189 {
12190 double vy;
12191 6 double vx = (value / 10000.0);
12192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (s->angular)
12193 vy = zc::math::Sin(s->angle)*s->step;
12194 else
12195 {
12196
5/7
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
6 switch(NORMAL_DIR(s->dir))
12197 {
12198 case l_up:
12199 case r_up:
12200 case up:
12201 2 vy = -1.0*s->step;
12202 2 break;
12203 case l_down:
12204 case r_down:
12205 case down:
12206 2 vy = s->step;
12207 2 break;
12208
12209 default:
12210 2 vy = 0;
12211 2 break;
12212 }
12213 }
12214 6 s->angular = true;
12215 6 s->angle=atan2(vy, vx);
12216 6 s->step=FFCore.Distance(0, 0, vx, vy)/10000.0;
12217 6 s->doAutoRotate();
12218 6 }
12219
12220 6 break;
12221
12222 case LWPNVY:
12223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12224 {
12225 double vx;
12226 6 double vy = (value / 10000.0);
12227
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (s->angular)
12228 6 vx = zc::math::Cos(s->angle)*s->step;
12229 else
12230 {
12231 switch(NORMAL_DIR(s->dir))
12232 {
12233 case l_up:
12234 case l_down:
12235 case left:
12236 vx = -1.0*s->step;
12237 break;
12238 case r_down:
12239 case r_up:
12240 case right:
12241 vx = s->step;
12242 break;
12243
12244 default:
12245 vx = 0;
12246 break;
12247 }
12248 }
12249 6 s->angular = true;
12250 6 s->angle=atan2(vy, vx);
12251 6 s->step=FFCore.Distance(0, 0, vx, vy)/10000.0;
12252 6 s->doAutoRotate();
12253 6 }
12254
12255 6 break;
12256
12257 case LWPNANGULAR:
12258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1441 times.
1441 if(auto s=checkLWpn(GET_REF(lwpnref)))
12259 {
12260 1441 s->angular=(value!=0);
12261 1441 s->doAutoRotate(false, true);
12262 1441 }
12263
12264 1441 break;
12265
12266 case LWPNAUTOROTATE:
12267 if(auto s=checkLWpn(GET_REF(lwpnref)))
12268 {
12269 s->autorotate=(value!=0);
12270 s->doAutoRotate(false, true);
12271 }
12272
12273 break;
12274
12275 case LWPNBEHIND:
12276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6730 times.
6730 if(auto s=checkLWpn(GET_REF(lwpnref)))
12277 6730 s->behind=(value!=0);
12278
12279 6730 break;
12280
12281 case LWPNDRAWTYPE:
12282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 476 times.
476 if(auto s=checkLWpn(GET_REF(lwpnref)))
12283 476 s->drawstyle=(value/10000);
12284
12285 476 break;
12286
12287 case LWPNPOWER:
12288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 148992 times.
148992 if(auto s=checkLWpn(GET_REF(lwpnref)))
12289 148992 s->power=(value/10000);
12290
12291 148992 break;
12292 case LWPNDEAD:
12293
2/2
✓ Branch 0 taken 6717 times.
✓ Branch 1 taken 147806 times.
154523 if(auto s=checkLWpn(GET_REF(lwpnref)))
12294 {
12295 147806 auto dead = value/10000;
12296 147806 s->dead=dead;
12297
2/2
✓ Branch 0 taken 75515 times.
✓ Branch 1 taken 72291 times.
147806 if(dead != 0) s->weapon_dying_frame = false;
12298 147806 }
12299 154523 break;
12300
12301 case LWPNTYPE:
12302 if(auto s=checkLWpn(GET_REF(lwpnref)))
12303 s->id=(value/10000);
12304
12305 break;
12306
12307 case LWPNTILE:
12308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2464 times.
2464 if(auto s=checkLWpn(GET_REF(lwpnref)))
12309 2464 s->tile=(value/10000);
12310
12311 2464 break;
12312
12313 case LWPNSCRIPTTILE:
12314
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3263 times.
3263 if(auto s=checkLWpn(GET_REF(lwpnref)))
12315 3263 s->scripttile=vbound((value/10000),-1,NEWMAXTILES-1);
12316
12317 3263 break;
12318
12319 case LWPNSCRIPTFLIP:
12320 if(auto s=checkLWpn(GET_REF(lwpnref)))
12321 s->scriptflip=vbound((value/10000),-1,127);
12322
12323 break;
12324
12325 case LWPNCSET:
12326
1/2
✓ Branch 0 taken 26540 times.
✗ Branch 1 not taken.
26540 if(auto s=checkLWpn(GET_REF(lwpnref)))
12327 26540 s->cs=(value/10000)&15;
12328
12329 26540 break;
12330
12331 case LWPNFLASHCSET:
12332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12333 6 (s->o_cset)|=(value/10000)<<4;
12334
12335 6 break;
12336
12337 case LWPNFRAMES:
12338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 429 times.
429 if(auto s=checkLWpn(GET_REF(lwpnref)))
12339 429 s->frames=(value/10000);
12340
12341 429 break;
12342
12343 case LWPNFRAME:
12344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12345 6 s->aframe=(value/10000);
12346
12347 6 break;
12348
12349 case LWPNASPEED:
12350
1/2
✓ Branch 0 taken 787 times.
✗ Branch 1 not taken.
787 if(auto s=checkLWpn(GET_REF(lwpnref)))
12351 787 s->o_speed=(value/10000);
12352
12353 787 break;
12354
12355 case LWPNFLASH:
12356
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12357 6 s->flash=(value/10000);
12358
12359 6 break;
12360
12361 case LWPNFLIP:
12362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 885 times.
885 if(auto s=checkLWpn(GET_REF(lwpnref)))
12363 885 s->flip=(value/10000);
12364
12365 885 break;
12366
12367 case LWPNROTATION:
12368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4922 times.
4922 if ( get_qr(qr_OLDSPRITEDRAWS) )
12369 {
12370 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
12371 break;
12372 }
12373
1/2
✓ Branch 0 taken 4922 times.
✗ Branch 1 not taken.
4922 if(auto s=checkLWpn(GET_REF(lwpnref)))
12374 4922 s->rotation=(value/10000);
12375
12376 4922 break;
12377
12378 case LWPNEXTEND:
12379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 839 times.
839 if(auto s=checkLWpn(GET_REF(lwpnref)))
12380 839 s->extend=(value/10000);
12381
12382 839 break;
12383
12384 case LWPNOTILE:
12385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2465 times.
2465 if(auto s=checkLWpn(GET_REF(lwpnref)))
12386 {
12387 2465 s->o_tile=(value/10000);
12388 2465 s->ref_o_tile=(value/10000);
12389 //s->script_wrote_otile=1; //Removing this as of 26th October, 2019 -Z
12390 //if at some future point we WANT writing ->Tile to also overwrite ->OriginalTile,
12391 //then either the user will need to manually write tile, or we can add a QR and
12392 // write ->tile here. 'script_wrote_otile' is out.
12393 2465 }
12394 2465 break;
12395
12396 case LWPNOCSET:
12397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12398 6 (s->o_cset)|=(value/10000)&15;
12399
12400 6 break;
12401
12402 case LWPNHXOFS:
12403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71310 times.
71310 if(auto s=checkLWpn(GET_REF(lwpnref)))
12404 71310 (s->hxofs)=(value/10000);
12405
12406 71310 break;
12407
12408 case LWPNHYOFS:
12409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71308 times.
71308 if(auto s=checkLWpn(GET_REF(lwpnref)))
12410 71308 (s->hyofs)=(value/10000);
12411
12412 71308 break;
12413
12414 case LWPNXOFS:
12415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1768 times.
1768 if(auto s=checkLWpn(GET_REF(lwpnref)))
12416 1768 (s->xofs)=(zfix)(value/10000);
12417
12418 1768 break;
12419
12420 case LWPNYOFS:
12421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70954 times.
70954 if(auto s=checkLWpn(GET_REF(lwpnref)))
12422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70954 times.
70954 (s->yofs)=(zfix)(value/10000)+(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
12423
12424 70954 break;
12425
12426 case LWPNSHADOWXOFS:
12427 if(auto s=checkLWpn(GET_REF(lwpnref)))
12428 (s->shadowxofs)=(zfix)(value/10000);
12429
12430 break;
12431
12432 case LWPNSHADOWYOFS:
12433 if(auto s=checkLWpn(GET_REF(lwpnref)))
12434 (s->shadowyofs)=(zfix)(value/10000);
12435
12436 break;
12437
12438 case LWPNTOTALDYOFFS:
12439 break; //READ-ONLY
12440
12441 case LWPNZOFS:
12442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12443 6 (s->zofs)=(zfix)(value/10000);
12444
12445 6 break;
12446
12447 case LWPNHXSZ:
12448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72525 times.
72525 if(auto s=checkLWpn(GET_REF(lwpnref)))
12449 72525 (s->hit_width)=(value/10000);
12450
12451 72525 break;
12452
12453 case LWPNHYSZ:
12454
1/2
✓ Branch 0 taken 72542 times.
✗ Branch 1 not taken.
72542 if(auto s=checkLWpn(GET_REF(lwpnref)))
12455 72542 (s->hit_height)=(value/10000);
12456
12457 72542 break;
12458
12459 case LWPNHZSZ:
12460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(auto s=checkLWpn(GET_REF(lwpnref)))
12461 6 (s->hzsz)=(value/10000);
12462
12463 6 break;
12464
12465 case LWPNTXSZ:
12466
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 833 times.
833 if(auto s=checkLWpn(GET_REF(lwpnref)))
12467 833 (s->txsz)=vbound((value/10000),1,20);
12468
12469 833 break;
12470
12471 case LWPNTYSZ:
12472
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 833 times.
833 if(auto s=checkLWpn(GET_REF(lwpnref)))
12473 833 (s->tysz)=vbound((value/10000),1,20);
12474
12475 833 break;
12476
12477 case LWPNCOLLDET:
12478
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25012 times.
25012 if(auto s=checkLWpn(GET_REF(lwpnref)))
12479 25012 (s->scriptcoldet) = value;
12480
12481 25012 break;
12482
12483 case LWPNENGINEANIMATE:
12484 if(auto s=checkLWpn(GET_REF(lwpnref)))
12485 (s->do_animation)=value;
12486
12487 break;
12488
12489 case LWPNPARENT:
12490 {
12491 //int32_t pitm = (vbound(value/10000,1,(MAXITEMS-1)));
12492
12493
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if(auto s=checkLWpn(GET_REF(lwpnref)))
12494 42 (s->parentitem)=(vbound(value/10000,-1,(MAXITEMS-1)));
12495 42 break;
12496 }
12497
12498 case LWPNLEVEL:
12499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(auto s=checkLWpn(GET_REF(lwpnref)))
12500 12 (s->level)=value/10000;
12501
12502 12 break;
12503
12504 case LWPNSCRIPT:
12505
1/2
✓ Branch 0 taken 68360 times.
✗ Branch 1 not taken.
68360 if(auto s=checkLWpn(GET_REF(lwpnref)))
12506 {
12507 68360 (s->script)=vbound(value/10000,0,NUMSCRIPTWEAPONS-1);
12508
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68360 times.
68360 if ( get_qr(qr_CLEARINITDONSCRIPTCHANGE))
12509 {
12510
2/2
✓ Branch 0 taken 546880 times.
✓ Branch 1 taken 68360 times.
615240 for(int32_t q=0; q<8; q++)
12511 546880 (s->initD[q]) = 0;
12512 68360 }
12513 68360 on_reassign_script_engine_data(ScriptType::Lwpn, ri->lwpnref);
12514 68360 }
12515 68360 break;
12516
12517 case LWPNUSEWEAPON:
12518
1/2
✓ Branch 0 taken 1130 times.
✗ Branch 1 not taken.
1130 if(auto s=checkLWpn(GET_REF(lwpnref)))
12519 1130 (s->useweapon)=vbound(value/10000,0,255);
12520
12521 1130 break;
12522
12523 case LWPNUSEDEFENCE:
12524 if(auto s=checkLWpn(GET_REF(lwpnref)))
12525 (s->usedefense)=vbound(value/10000,0,255);
12526
12527 break;
12528
12529 case LWPNFALLCLK:
12530 if(auto s=checkLWpn(GET_REF(lwpnref)))
12531 {
12532 if(s->fallclk != 0 && value == 0)
12533 {
12534 s->cs = s->o_cset;
12535 s->tile = s->o_tile;
12536 }
12537 else if(s->fallclk == 0 && value != 0) s->o_cset = s->cs;
12538 s->fallclk = vbound(value/10000,0,70);
12539 }
12540 break;
12541 case LWPNFALLCMB:
12542 if(auto s=checkLWpn(GET_REF(lwpnref)))
12543 {
12544 s->fallCombo = vbound(value/10000,0,MAXCOMBOS-1);
12545 }
12546 break;
12547 case LWPNDROWNCLK:
12548 if(auto s=checkLWpn(GET_REF(lwpnref)))
12549 {
12550 if(s->drownclk != 0 && value == 0)
12551 {
12552 s->cs = s->o_cset;
12553 s->tile = s->o_tile;
12554 }
12555 else if(s->drownclk == 0 && value != 0) s->o_cset = s->cs;
12556 s->drownclk = vbound(value/10000,0,70);
12557 }
12558 break;
12559 case LWPNDROWNCMB:
12560 if(auto s=checkLWpn(GET_REF(lwpnref)))
12561 {
12562 s->drownCombo = vbound(value/10000,0,MAXCOMBOS-1);
12563 }
12564 break;
12565 case LWPNFAKEZ:
12566 if(auto s=checkLWpn(GET_REF(lwpnref)))
12567 {
12568 s->fakez=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12569 if(s->fakez < 0) s->fakez = 0_zf;
12570 }
12571
12572 break;
12573
12574 case LWPNGLOWRAD:
12575
1/2
✓ Branch 0 taken 527 times.
✗ Branch 1 not taken.
527 if(auto s=checkLWpn(GET_REF(lwpnref)))
12576 {
12577 527 s->glowRad = vbound(value/10000,0,255);
12578 527 }
12579 527 break;
12580
12581 case LWPNGLOWSHP:
12582 if(auto s=checkLWpn(GET_REF(lwpnref)))
12583 {
12584 s->glowShape = vbound(value/10000,0,255);
12585 }
12586 break;
12587
12588 case LWPNUNBL:
12589 if(auto s=checkLWpn(GET_REF(lwpnref)))
12590 {
12591 s->unblockable = (value/10000)&WPNUNB_ALL;
12592 }
12593 break;
12594
12595 case LWPNSHADOWSPR:
12596 if(auto s=checkLWpn(GET_REF(lwpnref)))
12597 {
12598 s->spr_shadow = vbound(value/10000, 0, 255);
12599 }
12600 break;
12601 case LWSWHOOKED:
12602 break; //read-only
12603 case LWPNTIMEOUT:
12604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72192 times.
72192 if(auto s=checkLWpn(GET_REF(lwpnref)))
12605 {
12606 72192 s->weap_timeout = vbound(value/10000,0,214748);
12607 72192 }
12608 72192 break;
12609 case LWPNDEATHITEM:
12610 if(auto s=checkLWpn(GET_REF(lwpnref)))
12611 {
12612 s->death_spawnitem = vbound(value/10000,-1,MAXITEMS-1);
12613 }
12614 break;
12615 case LWPNDEATHDROPSET:
12616 if(auto s=checkLWpn(GET_REF(lwpnref)))
12617 {
12618 s->death_spawndropset = vbound(value/10000,-1,MAXITEMDROPSETS-1);
12619 }
12620 break;
12621 case LWPNDEATHIPICKUP:
12622 if(auto s=checkLWpn(GET_REF(lwpnref)))
12623 {
12624 s->death_item_pflags = value/10000;
12625 }
12626 break;
12627 case LWPNDEATHSPRITE:
12628 if(auto s=checkLWpn(GET_REF(lwpnref)))
12629 {
12630 s->death_sprite = vbound(value/10000,-255,MAXWPNS-1);
12631 }
12632 break;
12633 case LWPNDEATHSFX:
12634 if(auto s=checkLWpn(GET_REF(lwpnref)))
12635 {
12636 s->death_sfx = vbound(value/10000,0,WAV_COUNT);
12637 }
12638 break;
12639 case LWPNLIFTLEVEL:
12640 if(auto s=checkLWpn(GET_REF(lwpnref)))
12641 {
12642 s->lift_level = vbound(value/10000,0,255);
12643 }
12644 break;
12645 case LWPNLIFTTIME:
12646 if(auto s=checkLWpn(GET_REF(lwpnref)))
12647 {
12648 s->lift_time = vbound(value/10000,0,255);
12649 }
12650 break;
12651 case LWPNLIFTHEIGHT:
12652 if(auto s=checkLWpn(GET_REF(lwpnref)))
12653 {
12654 s->lift_height = zslongToFix(value);
12655 }
12656 break;
12657
12658 ///----------------------------------------------------------------------------------------------------//
12659 //EWeapon Variables
12660 case EWPNSCALE:
12661 if ( get_qr(qr_OLDSPRITEDRAWS) )
12662 {
12663 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'.");
12664 break;
12665 }
12666 if(auto s=checkEWpn(GET_REF(ewpnref)))
12667 s->scale=(zfix)(value/100.0);
12668
12669 break;
12670
12671 case EWPNX:
12672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 390184 times.
390184 if(auto s=checkEWpn(GET_REF(ewpnref)))
12673
2/2
✓ Branch 0 taken 38745 times.
✓ Branch 1 taken 351439 times.
390184 s->x = (get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000));
12674
12675 390184 break;
12676
12677 case SPRITEMAXEWPN:
12678 {
12679 //No bounds check, as this is a universal function and works from NULL pointers!
12680 30 Ewpns.setMax(vbound((value/10000),1,MAX_EWPN_SPRITES));
12681 30 break;
12682 }
12683
12684 case EWPNY:
12685
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 390781 times.
390781 if(auto s=checkEWpn(GET_REF(ewpnref)))
12686
2/2
✓ Branch 0 taken 38611 times.
✓ Branch 1 taken 352170 times.
390781 s->y = (get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000));
12687
12688 390781 break;
12689
12690 case EWPNZ:
12691
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57530 times.
57530 if(auto s=checkEWpn(GET_REF(ewpnref)))
12692 {
12693
2/2
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 56239 times.
57530 s->z=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
12694
2/2
✓ Branch 0 taken 411 times.
✓ Branch 1 taken 57119 times.
57530 if(s->z < 0) s->z = 0_zf;
12695 57530 }
12696
12697 57530 break;
12698
12699 case EWPNJUMP:
12700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55587 times.
55587 if(auto s=checkEWpn(GET_REF(ewpnref)))
12701 55587 s->fall=zslongToFix(value)*-100;
12702
12703 55587 break;
12704
12705 case EWPNFAKEJUMP:
12706 if(auto s=checkEWpn(GET_REF(ewpnref)))
12707 s->fakefall=zslongToFix(value)*-100;
12708
12709 break;
12710
12711 case EWPNDIR:
12712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 227257 times.
227257 if(auto s=checkEWpn(GET_REF(ewpnref)))
12713 {
12714 227257 s->dir=(value/10000);
12715 227257 s->doAutoRotate(true);
12716 227257 }
12717
12718 227257 break;
12719
12720 case EWPNLEVEL:
12721
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 if(auto s=checkEWpn(GET_REF(ewpnref)))
12722 117 s->level=(value/10000);
12723
12724 117 break;
12725
12726 case EWPNGRAVITY:
12727 if(auto s=checkEWpn(GET_REF(ewpnref)))
12728 {
12729 if(value)
12730 s->moveflags |= move_obeys_grav;
12731 else
12732 s->moveflags &= ~move_obeys_grav;
12733 }
12734 break;
12735
12736 case EWPNSTEP:
12737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 457872 times.
457872 if(auto s=checkEWpn(GET_REF(ewpnref)))
12738 {
12739
3/4
✓ Branch 0 taken 350322 times.
✓ Branch 1 taken 107550 times.
✓ Branch 2 taken 350322 times.
✗ Branch 3 not taken.
457872 if ( get_qr(qr_STEP_IS_FLOAT) || replay_is_active() )
12740 {
12741 457872 s->step= zslongToFix(value / 100);
12742 457872 }
12743 else
12744 {
12745 //old, buggy code replication, round two: Go! -Z
12746 //zfix val = zslongToFix(value);
12747 //val.doFloor();
12748 //s->step = ((val / 100.0).getFloat());
12749
12750 //old, buggy code replication, round THREE: Go! -Z
12751 s->step = ((value/10000)/100.0);
12752 }
12753 457872 }
12754
12755 457872 break;
12756
12757 case EWPNANGLE:
12758
2/2
✓ Branch 0 taken 305555 times.
✓ Branch 1 taken 6 times.
305561 if(auto s=checkEWpn(GET_REF(ewpnref)))
12759 {
12760 305555 s->angle=(double)(value/10000.0);
12761 305555 s->doAutoRotate();
12762 305555 }
12763
12764 305561 break;
12765
12766 case EWPNDEGANGLE:
12767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 93 times.
93 if(auto s=checkEWpn(GET_REF(ewpnref)))
12768 {
12769 93 double rangle = (value / 10000.0) * (PI / 180.0);
12770 93 s->angle=(double)(rangle);
12771 93 s->doAutoRotate();
12772 93 }
12773
12774 93 break;
12775
12776 case EWPNVX:
12777 if(auto s=checkEWpn(GET_REF(ewpnref)))
12778 {
12779 double vy;
12780 double vx = (value / 10000.0);
12781 if (s->angular)
12782 vy = zc::math::Sin(s->angle)*s->step;
12783 else
12784 {
12785 switch(NORMAL_DIR(s->dir))
12786 {
12787 case l_up:
12788 case r_up:
12789 case up:
12790 vy = -1.0*s->step;
12791 break;
12792 case l_down:
12793 case r_down:
12794 case down:
12795 vy = s->step;
12796 break;
12797
12798 default:
12799 vy = 0;
12800 break;
12801 }
12802 }
12803 s->angular = true;
12804 s->angle=atan2(vy, vx);
12805 s->step=FFCore.Distance(0, 0, vx, vy)/10000;
12806 s->doAutoRotate();
12807 }
12808
12809 break;
12810
12811 case EWPNVY:
12812 if(auto s=checkEWpn(GET_REF(ewpnref)))
12813 {
12814 double vx;
12815 double vy = (value / 10000.0);
12816 if (s->angular)
12817 vx = zc::math::Cos(s->angle)*s->step;
12818 else
12819 {
12820 switch(NORMAL_DIR(s->dir))
12821 {
12822 case l_up:
12823 case l_down:
12824 case left:
12825 vx = -1.0*s->step;
12826 break;
12827 case r_down:
12828 case r_up:
12829 case right:
12830 vx = s->step;
12831 break;
12832
12833 default:
12834 vx = 0;
12835 break;
12836 }
12837 }
12838 s->angular = true;
12839 s->angle=atan2(vy, vx);
12840 s->step=FFCore.Distance(0, 0, vx, vy)/10000;
12841 s->doAutoRotate();
12842 }
12843
12844 break;
12845
12846 case EWPNANGULAR:
12847
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 293753 times.
293753 if(auto s=checkEWpn(GET_REF(ewpnref)))
12848 {
12849 293753 s->angular=(value!=0);
12850 293753 s->doAutoRotate(false, true);
12851 293753 }
12852
12853 293753 break;
12854
12855 case EWPNAUTOROTATE:
12856 if(auto s=checkEWpn(GET_REF(ewpnref)))
12857 {
12858 s->autorotate=(value!=0);
12859 s->doAutoRotate(false, true);
12860 }
12861
12862 break;
12863
12864 case EWPNBEHIND:
12865
1/2
✓ Branch 0 taken 7539 times.
✗ Branch 1 not taken.
7539 if(auto s=checkEWpn(GET_REF(ewpnref)))
12866 7539 s->behind=(value!=0);
12867
12868 7539 break;
12869
12870 case EWPNDRAWTYPE:
12871
1/2
✓ Branch 0 taken 12175 times.
✗ Branch 1 not taken.
12175 if(auto s=checkEWpn(GET_REF(ewpnref)))
12872 12175 s->drawstyle=(value/10000);
12873
12874 12175 break;
12875
12876 case EWPNPOWER:
12877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 305977 times.
305977 if(auto s=checkEWpn(GET_REF(ewpnref)))
12878 305977 s->power=(value/10000);
12879
12880 305977 break;
12881
12882 case EWPNDEAD:
12883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 398520 times.
398520 if(auto s=checkEWpn(GET_REF(ewpnref)))
12884 {
12885 398520 auto dead = value/10000;
12886 398520 s->dead=dead;
12887
2/2
✓ Branch 0 taken 88001 times.
✓ Branch 1 taken 310519 times.
398520 if(dead != 0) s->weapon_dying_frame = false;
12888 398520 }
12889
12890 398520 break;
12891
12892 case EWPNTYPE:
12893 if(auto s=checkEWpn(GET_REF(ewpnref)))
12894 s->id=(value/10000);
12895
12896 break;
12897
12898 case EWPNTILE:
12899
1/2
✓ Branch 0 taken 74446 times.
✗ Branch 1 not taken.
74446 if(auto s=checkEWpn(GET_REF(ewpnref)))
12900 74446 s->tile=(value/10000);
12901
12902 74446 break;
12903
12904 case EWPNSCRIPTTILE:
12905
1/2
✓ Branch 0 taken 178 times.
✗ Branch 1 not taken.
178 if(auto s=checkEWpn(GET_REF(ewpnref)))
12906 178 s->scripttile=vbound((value/10000),-1, NEWMAXTILES-1);
12907
12908 178 break;
12909
12910 case EWPNSCRIPTFLIP:
12911 if(auto s=checkEWpn(GET_REF(ewpnref)))
12912 s->scriptflip=vbound((value/10000),-1, 127);
12913
12914 break;
12915
12916 case EWPNCSET:
12917
1/2
✓ Branch 0 taken 35337 times.
✗ Branch 1 not taken.
35337 if(auto s=checkEWpn(GET_REF(ewpnref)))
12918 35337 s->cs=(value/10000)&15;
12919
12920 35337 break;
12921
12922 case EWPNFLASHCSET:
12923 if(auto s=checkEWpn(GET_REF(ewpnref)))
12924 (s->o_cset)|=(value/10000)<<4;
12925
12926 break;
12927
12928 case EWPNFRAMES:
12929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if(auto s=checkEWpn(GET_REF(ewpnref)))
12930 199 s->frames=(value/10000);
12931
12932 199 break;
12933
12934 case EWPNFRAME:
12935
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1039 times.
1039 if(auto s=checkEWpn(GET_REF(ewpnref)))
12936 1039 s->aframe=(value/10000);
12937
12938 1039 break;
12939
12940 case EWPNASPEED:
12941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 if(auto s=checkEWpn(GET_REF(ewpnref)))
12942 199 s->o_speed=(value/10000);
12943
12944 199 break;
12945
12946 case EWPNFLASH:
12947
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 549 times.
549 if(auto s=checkEWpn(GET_REF(ewpnref)))
12948 549 s->flash=(value/10000);
12949
12950 549 break;
12951
12952 case EWPNFLIP:
12953
1/2
✓ Branch 0 taken 78832 times.
✗ Branch 1 not taken.
78832 if(auto s=checkEWpn(GET_REF(ewpnref)))
12954 78832 s->flip=(value/10000);
12955
12956 78832 break;
12957
12958 case EWPNROTATION:
12959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1104 times.
1104 if ( get_qr(qr_OLDSPRITEDRAWS) )
12960 {
12961 scripting_log_error_with_context("To use this you must disable the quest rule 'Old (Faster) Sprite Drawing'");
12962 break;
12963 }
12964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1104 times.
1104 if(auto s=checkEWpn(GET_REF(ewpnref)))
12965 1104 s->rotation=(value/10000);
12966
12967 1104 break;
12968
12969 case EWPNEXTEND:
12970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156969 times.
156969 if(auto s=checkEWpn(GET_REF(ewpnref)))
12971 156969 s->extend=(value/10000);
12972
12973 156969 break;
12974
12975 case EWPNOTILE:
12976
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4552 times.
4552 if(auto s=checkEWpn(GET_REF(ewpnref)))
12977 {
12978 4552 s->o_tile=(value/10000);
12979 4552 s->ref_o_tile=(value/10000);
12980 4552 }
12981
12982 4552 break;
12983
12984 case EWPNOCSET:
12985 if(auto s=checkEWpn(GET_REF(ewpnref)))
12986 (s->o_cset)|=(value/10000)&15;
12987
12988 break;
12989
12990 case EWPNHXOFS:
12991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 194229 times.
194229 if(auto s=checkEWpn(GET_REF(ewpnref)))
12992 194229 (s->hxofs)=(value/10000);
12993
12994 194229 break;
12995
12996 case EWPNHYOFS:
12997
1/2
✓ Branch 0 taken 193736 times.
✗ Branch 1 not taken.
193736 if(auto s=checkEWpn(GET_REF(ewpnref)))
12998 193736 (s->hyofs)=(value/10000);
12999
13000 193736 break;
13001
13002 case EWPNXOFS:
13003
2/2
✓ Branch 0 taken 84990 times.
✓ Branch 1 taken 4 times.
84994 if(auto s=checkEWpn(GET_REF(ewpnref)))
13004 84990 (s->xofs)=(zfix)(value/10000);
13005
13006 84994 break;
13007
13008 case EWPNYOFS:
13009
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44193 times.
44193 if(auto s=checkEWpn(GET_REF(ewpnref)))
13010
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44193 times.
44193 (s->yofs)=(zfix)(value/10000)+(get_qr(qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
13011
13012 44193 break;
13013
13014 case EWPNSHADOWXOFS:
13015 if(auto s=checkEWpn(GET_REF(ewpnref)))
13016 (s->shadowxofs)=(zfix)(value/10000);
13017
13018 break;
13019
13020 case EWPNSHADOWYOFS:
13021 if(auto s=checkEWpn(GET_REF(ewpnref)))
13022 (s->shadowyofs)=(zfix)(value/10000);
13023
13024 break;
13025
13026 case EWPNZOFS:
13027 if(auto s=checkEWpn(GET_REF(ewpnref)))
13028 (s->zofs)=(zfix)(value/10000);
13029
13030 break;
13031
13032 case EWPNHXSZ:
13033
1/2
✓ Branch 0 taken 325611 times.
✗ Branch 1 not taken.
325611 if(auto s=checkEWpn(GET_REF(ewpnref)))
13034 325611 (s->hit_width)=(value/10000);
13035
13036 325611 break;
13037
13038 case EWPNHYSZ:
13039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325024 times.
325024 if(auto s=checkEWpn(GET_REF(ewpnref)))
13040 325024 (s->hit_height)=(value/10000);
13041
13042 325024 break;
13043
13044 case EWPNHZSZ:
13045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44 times.
44 if(auto s=checkEWpn(GET_REF(ewpnref)))
13046 44 (s->hzsz)=(value/10000);
13047
13048 44 break;
13049
13050 case EWPNTXSZ:
13051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202345 times.
202345 if(auto s=checkEWpn(GET_REF(ewpnref)))
13052 202345 (s->txsz)=vbound((value/10000),1,20);
13053
13054 202345 break;
13055
13056 case EWPNTYSZ:
13057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 202345 times.
202345 if(auto s=checkEWpn(GET_REF(ewpnref)))
13058 202345 (s->tysz)=vbound((value/10000),1,20);
13059
13060 202345 break;
13061
13062 case EWPNCOLLDET:
13063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37812 times.
37812 if(auto s=checkEWpn(GET_REF(ewpnref)))
13064 37812 (s->scriptcoldet)=value;
13065
13066 37812 break;
13067
13068 case EWPNENGINEANIMATE:
13069 if(auto s=checkEWpn(GET_REF(ewpnref)))
13070 (s->do_animation)=value;
13071
13072 break;
13073
13074
13075 case EWPNPARENTUID:
13076 if(auto s=checkEWpn(GET_REF(ewpnref)))
13077 s->setParent(sprite::getByUID(value));
13078 break;
13079
13080 case EWPNPARENT:
13081 if(auto s=checkEWpn(GET_REF(ewpnref)))
13082 (s->parentid)= ( (get_qr(qr_OLDEWPNPARENT)) ? value / 10000 : value );
13083
13084 break;
13085
13086 case EWPNSCRIPT:
13087
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5519 times.
5519 if(auto s=checkEWpn(GET_REF(ewpnref)))
13088 {
13089 5519 (s->script)=vbound(value/10000,0,NUMSCRIPTWEAPONS-1);
13090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5519 times.
5519 if ( get_qr(qr_CLEARINITDONSCRIPTCHANGE))
13091 {
13092
2/2
✓ Branch 0 taken 44152 times.
✓ Branch 1 taken 5519 times.
49671 for(int32_t q=0; q<8; q++)
13093 44152 (s->initD[q]) = 0;
13094 5519 }
13095 5519 on_reassign_script_engine_data(ScriptType::Ewpn, ri->ewpnref);
13096 5519 }
13097 5519 break;
13098
13099 case EWPNFALLCLK:
13100 if(auto s=checkEWpn(GET_REF(ewpnref)))
13101 {
13102 if(s->fallclk != 0 && value == 0)
13103 {
13104 s->cs = s->o_cset;
13105 s->tile = s->o_tile;
13106 }
13107 else if(s->fallclk == 0 && value != 0) s->o_cset = s->cs;
13108 s->fallclk = vbound(value/10000,0,70);
13109 }
13110 break;
13111 case EWPNFALLCMB:
13112 if(auto s=checkEWpn(GET_REF(ewpnref)))
13113 {
13114 s->fallCombo = vbound(value/10000,0,MAXCOMBOS-1);
13115 }
13116 break;
13117 case EWPNDROWNCLK:
13118 if(auto s=checkEWpn(GET_REF(ewpnref)))
13119 {
13120 if(s->drownclk != 0 && value == 0)
13121 {
13122 s->cs = s->o_cset;
13123 s->tile = s->o_tile;
13124 }
13125 else if(s->drownclk == 0 && value != 0) s->o_cset = s->cs;
13126 s->drownclk = vbound(value/10000,0,70);
13127 }
13128 break;
13129 case EWPNDROWNCMB:
13130 if(auto s=checkEWpn(GET_REF(ewpnref)))
13131 {
13132 s->drownCombo = vbound(value/10000,0,MAXCOMBOS-1);
13133 }
13134 break;
13135 case EWPNFAKEZ:
13136 if(auto s=checkEWpn(GET_REF(ewpnref)))
13137 {
13138 s->fakez=get_qr(qr_SPRITEXY_IS_FLOAT) ? zslongToFix(value) : zfix(value/10000);
13139 if(s->fakez < 0) s->fakez = 0_zf;
13140 }
13141
13142 break;
13143
13144 case EWPNGLOWRAD:
13145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(auto s=checkEWpn(GET_REF(ewpnref)))
13146 {
13147 4 s->glowRad = vbound(value/10000,0,255);
13148 4 }
13149 4 break;
13150 case EWPNGLOWSHP:
13151 if(auto s=checkEWpn(GET_REF(ewpnref)))
13152 {
13153 s->glowShape = vbound(value/10000,0,255);
13154 }
13155 break;
13156
13157 case EWPNUNBL:
13158
1/2
✓ Branch 0 taken 8364 times.
✗ Branch 1 not taken.
8364 if(auto s=checkEWpn(GET_REF(ewpnref)))
13159 {
13160 8364 s->unblockable = (value/10000)&WPNUNB_ALL;
13161 8364 }
13162 8364 break;
13163
13164 case EWPNSHADOWSPR:
13165 if(auto s=checkEWpn(GET_REF(ewpnref)))
13166 {
13167 s->spr_shadow = vbound(value/10000, 0, 255);
13168 }
13169 break;
13170 case EWSWHOOKED:
13171 break; //read-only
13172 case EWPNTIMEOUT:
13173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 91132 times.
91132 if(auto s=checkEWpn(GET_REF(ewpnref)))
13174 {
13175 91132 s->weap_timeout = vbound(value/10000,0,214748);
13176 91132 }
13177 91132 break;case EWPNDEATHITEM:
13178 if(auto s=checkEWpn(GET_REF(ewpnref)))
13179 {
13180 s->death_spawnitem = vbound(value/10000,-1,MAXITEMS-1);
13181 }
13182 break;
13183 case EWPNDEATHDROPSET:
13184 if(auto s=checkEWpn(GET_REF(ewpnref)))
13185 {
13186 s->death_spawndropset = vbound(value/10000,-1,MAXITEMDROPSETS-1);
13187 }
13188 break;
13189 case EWPNDEATHIPICKUP:
13190 if(auto s=checkEWpn(GET_REF(ewpnref)))
13191 {
13192 s->death_item_pflags = value/10000;
13193 }
13194 break;
13195 case EWPNDEATHSPRITE:
13196 if(auto s=checkEWpn(GET_REF(ewpnref)))
13197 {
13198 s->death_sprite = vbound(value/10000,-255,MAXWPNS-1);
13199 }
13200 break;
13201 case EWPNDEATHSFX:
13202 if(auto s=checkEWpn(GET_REF(ewpnref)))
13203 {
13204 s->death_sfx = vbound(value/10000,0,WAV_COUNT);
13205 }
13206 break;
13207 case EWPNLIFTLEVEL:
13208 if(auto s=checkEWpn(GET_REF(ewpnref)))
13209 {
13210 s->lift_level = vbound(value/10000,0,255);
13211 }
13212 break;
13213 case EWPNLIFTTIME:
13214 if(auto s=checkEWpn(GET_REF(ewpnref)))
13215 {
13216 s->lift_time = vbound(value/10000,0,255);
13217 }
13218 break;
13219 case EWPNLIFTHEIGHT:
13220 if(auto s=checkEWpn(GET_REF(ewpnref)))
13221 {
13222 s->lift_height = zslongToFix(value);
13223 }
13224 break;
13225
13226 ///----------------------------------------------------------------------------------------------------//
13227 //Screen Information
13228
13229 case SCREENSCRDATASIZE:
13230 {
13231 int index = map_screen_index(cur_map, ri->screenref);
13232 if (index < 0) break;
13233
13234 game->scriptDataResize(index, value/10000);
13235 break;
13236 }
13237
13238 ///----------------------------------------------------------------------------------------------------//
13239 //BottleTypes
13240
13241 case BOTTLENEXT:
13242 {
13243 if(bottletype* ptr = checkBottleData(GET_REF(bottletyperef)))
13244 {
13245 ptr->next_type = vbound(value/10000, 0, 64);
13246 }
13247 }
13248 break;
13249
13250 ///----------------------------------------------------------------------------------------------------//
13251 //Viewport
13252
13253 case VIEWPORT_TARGET:
13254 {
13255
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (auto s = ResolveBaseSprite(value))
13256 6 set_viewport_sprite(s);
13257 }
13258 6 break;
13259
13260 case VIEWPORT_MODE:
13261 {
13262 4 int val = value;
13263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (BC::checkBounds(val, (int)ViewportMode::First, (int)ViewportMode::Last) != SH::_NoError)
13264 {
13265 break;
13266 }
13267
13268 4 viewport_mode = (ViewportMode)val;
13269 }
13270 4 break;
13271
13272 case VIEWPORT_X:
13273 {
13274 360 viewport.x = value / 10000;
13275 }
13276 360 break;
13277
13278 case VIEWPORT_Y:
13279 {
13280 360 viewport.y = value / 10000;
13281 }
13282 360 break;
13283
13284 case VIEWPORT_WIDTH:
13285 {
13286 int val = value / 10000;
13287 if (BC::checkBounds(val, 0, 256) != SH::_NoError)
13288 break;
13289
13290 viewport.w = val;
13291 }
13292 break;
13293
13294 case VIEWPORT_HEIGHT:
13295 {
13296 int val = value / 10000;
13297 if (BC::checkBounds(val, 0, 232) != SH::_NoError)
13298 break;
13299
13300 viewport.h = val;
13301 }
13302 break;
13303
13304 ///----------------------------------------------------------------------------------------------------//
13305 //Screen Variables
13306
13307 #define SET_SCREENDATA_VAR_INT32(member, str) \
13308 { \
13309 get_scr(GET_REF(screenref))->member = vbound((value / 10000),-214747,214747); \
13310 } \
13311
13312 #define SET_SCREENDATA_VAR_INT16(member, str) \
13313 { \
13314 get_scr(GET_REF(screenref))->member = vbound((value / 10000),0,32767); \
13315 } \
13316
13317 #define SET_SCREENDATA_VAR_BYTE(member, str) \
13318 { \
13319 get_scr(GET_REF(screenref))->member = vbound((value / 10000),0,255); \
13320 } \
13321
13322 #define SET_SCREENDATA_BYTE_INDEX(member, str, indexbound) \
13323 { \
13324 int32_t indx = GET_D(rINDEX) / 10000; \
13325 get_scr(GET_REF(screenref))->member[indx] = vbound((value / 10000),0,255); \
13326 }
13327
13328 ///max screen id is higher! vbound properly... -Z
13329 #define SET_SCREENDATA_LAYERSCREEN_INDEX(member, str, indexbound) \
13330 { \
13331 int32_t indx = GET_D(rINDEX) / 10000; \
13332 int32_t scrn_id = value/10000; \
13333 if ( FFCore.quest_format[vFFScript] < 11 ) ++indx; \
13334 if (BC::checkIndex(indx, 1, indexbound) != SH::_NoError) \
13335 { \
13336 } \
13337 else if ( scrn_id > MAPSCRS ) \
13338 { \
13339 Z_scripterrlog("Script attempted to use a mapdata->LayerScreen[%d].\n",scrn_id); \
13340 Z_scripterrlog("Valid Screen values are (0) through (%d).\n",MAPSCRS); \
13341 } \
13342 else get_scr(GET_REF(screenref))->member[indx-1] = vbound((scrn_id),0,MAPSCRS); \
13343 }
13344
13345 #define SET_SCREENDATA_FLAG(member, str) \
13346 { \
13347 int32_t flag = (value/10000); \
13348 if ( flag != 0 ) \
13349 { \
13350 get_scr(GET_REF(screenref))->member|=flag; \
13351 } \
13352 else get_scr(GET_REF(screenref))->.member|= ~flag; \
13353 } \
13354
13355 #define SET_SCREENDATA_BOOL_INDEX(member, str, indexbound) \
13356 { \
13357 int32_t indx = GET_D(rINDEX) / 10000; \
13358 if(indx < 0 || indx > indexbound ) \
13359 { \
13360 Z_scripterrlog("Invalid Index passed to Screen->%s[]: %d\n", (indx), str); \
13361 break; \
13362 } \
13363 get_scr(GET_REF(screenref))->member[indx] =( (value/10000) ? 1 : 0 ); \
13364 }
13365
13366 case SCREENDATAVALID:
13367 {
13368 SET_SCREENDATA_VAR_BYTE(valid, "Valid"); //b
13369 mark_current_region_handles_dirty();
13370 break;
13371 }
13372 case SCREENDATAGUY: SET_SCREENDATA_VAR_BYTE(guy, "Guy"); break; //b
13373 case SCREENDATASTRING: SET_SCREENDATA_VAR_INT32(str, "String"); break; //w
13374 case SCREENDATAROOM: SET_SCREENDATA_VAR_BYTE(room, "RoomType"); break; //b
13375 case SCREENDATAITEM:
13376 {
13377 auto v = vbound((value / 10000),-1,255);
13378 auto scr = get_scr(GET_REF(screenref));
13379 if(v > -1)
13380 scr->item = v;
13381 scr->hasitem = v > -1;
13382 break;
13383 }
13384 case SCREENDATAHASITEM: SET_SCREENDATA_VAR_BYTE(hasitem, "HasItem"); break; //b
13385 case SCREENDATADOORCOMBOSET: SET_SCREENDATA_VAR_INT32(door_combo_set, "DoorComboSet"); break; //w
13386 case SCREENDATAWARPRETURNC: SET_SCREENDATA_VAR_INT32(warpreturnc, "WarpReturnC"); break; //w
13387 case SCREENDATASTAIRX: SET_SCREENDATA_VAR_BYTE(stairx, "StairsX"); break; //b
13388 case SCREENDATASTAIRY: SET_SCREENDATA_VAR_BYTE(stairy, "StairsY"); break; //b
13389 case SCREENDATAITEMX: SET_SCREENDATA_VAR_BYTE(itemx, "ItemX"); break; //itemx
13390 case SCREENDATAITEMY: SET_SCREENDATA_VAR_BYTE(itemy, "ItemY"); break; //itemy
13391 case SCREENDATACOLOUR: SET_SCREENDATA_VAR_INT32(color, "CSet"); break; //w
13392 case SCREENDATAENEMYFLAGS: SET_SCREENDATA_VAR_BYTE(flags11, "EnemyFlags"); break; //b
13393 case SCREENDATADOOR: SET_SCREENDATA_BYTE_INDEX(door, "Door", 3); break; //b, 4 of these
13394 case SCREENDATAEXITDIR: SET_SCREENDATA_VAR_BYTE(exitdir, "ExitDir"); break; //b
13395 14 case SCREENDATAPATTERN: SET_SCREENDATA_VAR_BYTE(pattern, "Pattern"); break; //b
13396 case SCREENDATAWARPARRIVALX: SET_SCREENDATA_VAR_BYTE(warparrivalx, "WarpArrivalX"); break; //b
13397 case SCREENDATAWARPARRIVALY: SET_SCREENDATA_VAR_BYTE(warparrivaly, "WarpArrivalY"); break; //b
13398 case SCREENDATASIDEWARPINDEX: SET_SCREENDATA_VAR_BYTE(sidewarpindex, "SideWarpIndex"); break; //b
13399 case SCREENDATACATCHALL: SET_SCREENDATA_VAR_INT32(catchall, "Catchall"); break; //W
13400
13401 case SCREENDATACSENSITIVE: SET_SCREENDATA_VAR_BYTE(csensitive, "CSensitive"); break; //B
13402 case SCREENDATANORESET: SET_SCREENDATA_VAR_INT32(noreset, "NoReset"); break; //W
13403 case SCREENDATANOCARRY: SET_SCREENDATA_VAR_INT32(nocarry, "NoCarry"); break; //W
13404
13405 case SCREENDATATIMEDWARPTICS: SET_SCREENDATA_VAR_INT32(timedwarptics, "TimedWarpTimer"); break; //W
13406 case SCREENDATANEXTMAP: SET_SCREENDATA_VAR_BYTE(nextmap, "NextMap"); break; //B
13407 case SCREENDATANEXTSCREEN: SET_SCREENDATA_VAR_BYTE(nextscr, "NextScreen"); break; //B
13408 case SCREENDATAVIEWX: break;//SET_SCREENDATA_VAR_INT32(viewX, "ViewX"); break; //W
13409 case SCREENDATAVIEWY: break;//SET_SCREENDATA_VAR_INT32(viewY, "ViewY"); break; //W
13410 case SCREENDATASCREENWIDTH: break;//SET_SCREENDATA_VAR_BYTE(scrWidth, "Width"); break; //B
13411 case SCREENDATASCREENHEIGHT: break;//SET_SCREENDATA_VAR_BYTE(scrHeight, "Height"); break; //B
13412 case SCREENDATAENTRYX:
13413 {
13414 30 int32_t newx = vbound((value/10000),0,255);
13415 30 get_scr(GET_REF(screenref))->entry_x = newx;
13416
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
30 if ( get_qr(qr_WRITE_ENTRYPOINTS_AFFECTS_HEROCLASS) )
13417 {
13418 20 Hero.respawn_x = (zfix)(newx);
13419 20 }
13420 30 break;
13421 }
13422 case SCREENDATAENTRYY:
13423 {
13424
13425 30 int32_t newy = vbound((value/10000),0,175);
13426 30 get_scr(GET_REF(screenref))->entry_y = newy;
13427
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
30 if ( get_qr(qr_WRITE_ENTRYPOINTS_AFFECTS_HEROCLASS) )
13428 {
13429 20 Hero.respawn_y = (zfix)(newy);
13430 20 }
13431 30 break; //B
13432 }
13433
13434 case SCREENDATANUMFF:
13435 {
13436 break;
13437 }
13438
13439 case SCREENDATAFFINITIALISED:
13440 {
13441 int32_t indx = GET_D(rINDEX) / 10000;
13442 if (indx < 0 || indx > MAX_FFCID)
13443 {
13444 Z_scripterrlog("Invalid Index passed to Screen->%s[]: %d\n", "FFCRunning", (indx));
13445 break;
13446 }
13447 get_script_engine_data(ScriptType::FFC, indx).initialized = (value/10000) ? true : false;
13448 }
13449 break;
13450
13451 case SCREENDATASCRIPTENTRY:
13452 {
13453 Z_scripterrlog("Unimplemented: %s\n", "ScriptEntry");
13454 }
13455 break;
13456 case SCREENDATASCRIPTOCCUPANCY:
13457 {
13458 Z_scripterrlog("Unimplemented: %s\n", "ScriptOccupancy");
13459 }
13460 break;
13461 case SCREENDATASCRIPTEXIT:
13462 {
13463 Z_scripterrlog("Unimplemented: %s\n", "ExitScript");
13464 }
13465 break;
13466
13467 case SCREENDATAOCEANSFX:
13468 {
13469 int32_t v = vbound(value/10000, 0, 255);
13470 auto scr = get_scr(GET_REF(screenref));
13471 if (scr == hero_scr && scr->oceansfx != v)
13472 {
13473 stop_sfx(scr->oceansfx);
13474 scr->oceansfx = v;
13475 cont_sfx(scr->oceansfx);
13476 }
13477 break;
13478 }
13479 case SCREENDATABOSSSFX: SET_SCREENDATA_VAR_BYTE(bosssfx, "BossSFX"); break; //B
13480 10 case SCREENDATASECRETSFX: SET_SCREENDATA_VAR_BYTE(secretsfx, "SecretSFX"); break; //B
13481 case SCREENDATAHOLDUPSFX: SET_SCREENDATA_VAR_BYTE(holdupsfx, "ItemSFX"); break; //B
13482 case SCREENDATASCREENMIDI:
13483 {
13484 get_scr(GET_REF(screenref))->screen_midi = vbound((value / 10000)-(MIDIOFFSET_MAPSCR-MIDIOFFSET_ZSCRIPT),-1,32767);
13485 break;
13486 }
13487 case SCREENDATA_GRAVITY_STRENGTH:
13488 {
13489 get_scr(GET_REF(screenref))->screen_gravity = zslongToFix(value);
13490 break;
13491 }
13492 case SCREENDATA_TERMINAL_VELOCITY:
13493 {
13494 get_scr(GET_REF(screenref))->screen_terminal_v = zslongToFix(value);
13495 break;
13496 }
13497 case SCREENDATALENSLAYER: SET_SCREENDATA_VAR_BYTE(lens_layer, "LensLayer"); break; //B, OLD QUESTS ONLY?
13498
13499 case SCREENDATAGUYCOUNT:
13500 {
13501 int mi = mapind(cur_map, GET_REF(screenref));
13502 if(mi > -1)
13503 game->guys[mi] = vbound(value/10000,10,0);
13504 break;
13505 }
13506 case SCREENDATAEXDOOR:
13507 {
13508 int mi = mapind(cur_map, GET_REF(screenref));
13509 if(mi < 0) break;
13510 int dir = SH::read_stack(ri->sp+1) / 10000;
13511 int ind = SH::read_stack(ri->sp+0) / 10000;
13512 if(unsigned(dir) > 3)
13513 Z_scripterrlog("Invalid dir '%d' passed to 'Screen->SetExDoor()'; must be 0-3\n", dir);
13514 else if(unsigned(ind) > 7)
13515 Z_scripterrlog("Invalid index '%d' passed to 'Screen->SetExDoor()'; must be 0-7\n", ind);
13516 else
13517 set_xdoorstate_mi(mi, dir, ind);
13518 break;
13519 }
13520
13521 //These use the same method as SetScreenD
13522 case SCREENWIDTH:
13523 // FFScript::set_screenWidth(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)], value/10000);
13524 break;
13525
13526 case SCREENHEIGHT:
13527 // FFScript::set_screenHeight(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)], value/10000);
13528 break;
13529
13530 case SCREENVIEWX:
13531 // FFScript::set_screenViewX(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)], value/10000);
13532 break;
13533
13534 case SCREENVIEWY:
13535 // FFScript::set_screenViewY(&TheMaps[(GET_D(rINDEX2) / 10000) * MAPSCRS + (GET_D(rINDEX)/10000)], value/10000);
13536 break;
13537
13538 //These use the method of SetScreenEnemy
13539
13540 case GDD:
13541 write_array(game->global_d, GET_D(rINDEX) / 10000, value);
13542 break;
13543
13544 case SDDD:
13545 27297 FFScript::set_screen_d((GET_D(rINDEX))/10000 + ((get_currdmap())<<7), GET_D(rINDEX2)/10000, value);
13546 27297 break;
13547
13548 case SDDDD:
13549 537 FFScript::set_screen_d(GET_D(rINDEX2)/10000 + ((GET_D(rINDEX)/10000)<<7), GET_D(rEXP1)/10000, value);
13550 537 break;
13551
13552 case SCREENSCRIPT:
13553 {
13554 mapscr* scr = get_scr(GET_REF(screenref));
13555
13556 if ( get_qr(qr_CLEARINITDONSCRIPTCHANGE))
13557 {
13558 for(int32_t q=0; q<8; q++)
13559 scr->screeninitd[q] = 0;
13560 }
13561
13562 scr->script=vbound(value/10000, 0, NUMSCRIPTSCREEN-1);
13563 on_reassign_script_engine_data(ScriptType::Screen, ri->screenref);
13564 break;
13565 }
13566
13567 case LIT:
13568 900 set_lights(value);
13569 900 break;
13570
13571 case WAVY:
13572 7396 wavy=value/10000;
13573 7396 break;
13574
13575 case QUAKE:
13576 6728 quakeclk=value/10000;
13577 6728 break;
13578
13579 case ROOMTYPE:
13580 get_scr(GET_REF(screenref))->room=value/10000; break; //this probably doesn't work too well...
13581
13582 case ROOMDATA:
13583 11 get_scr(GET_REF(screenref))->catchall=value/10000;
13584 11 break;
13585
13586 case PUSHBLOCKLAYER:
13587 mblock2.blockLayer=vbound(value/10000, 0, 6);
13588 break;
13589
13590 case PUSHBLOCKCOMBO:
13591 mblock2.bcombo=value/10000;
13592 break;
13593
13594 case PUSHBLOCKCSET:
13595 mblock2.cs=value/10000;
13596 mblock2.oldcset=value/10000;
13597 break;
13598
13599 case UNDERCOMBO:
13600 get_scr(GET_REF(screenref))->undercombo=value/10000;
13601 break;
13602
13603 case UNDERCSET:
13604 get_scr(GET_REF(screenref))->undercset=value/10000;
13605 break;
13606
13607 case SCREEN_DRAW_ORIGIN:
13608
1/2
✓ Branch 0 taken 1853535 times.
✗ Branch 1 not taken.
1853535 if (BC::checkBounds(value, (int)DrawOrigin::First, (int)DrawOrigin::Last) != SH::_NoError)
13609 break;
13610
13611 1853535 ri->screen_draw_origin = (DrawOrigin)value;
13612 1853535 break;
13613
13614 case SCREEN_DRAW_ORIGIN_TARGET:
13615 {
13616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 606224 times.
606224 if (ResolveBaseSprite(value))
13617 606224 ri->screen_draw_origin_target = value;
13618
13619 606224 break;
13620 }
13621
13622 ///----------------------------------------------------------------------------------------------------//
13623 //New Datatype Variables
13624
13625 ///----------------------------------------------------------------------------------------------------//
13626 //spritedata sp-> Variables
13627 case SPRITEDATATILE: SET_SPRITEDATA_VAR_INT(tile, "Tile"); break;
13628 case SPRITEDATAMISC: SET_SPRITEDATA_VAR_BYTE(misc, "Misc"); break;
13629 case SPRITEDATACSETS:
13630 {
13631 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) )
13632 {
13633 Z_scripterrlog("Invalid Sprite ID passed to spritedata->CSet: %d\n", GET_REF(spritedataref));
13634 }
13635 else
13636 {
13637 wpnsbuf[GET_REF(spritedataref)].csets &= 0xF0;
13638 wpnsbuf[GET_REF(spritedataref)].csets |= vbound((value / 10000),0,15);
13639 }
13640 break;
13641 }
13642 case SPRITEDATAFLCSET:
13643 {
13644 if(unsigned(GET_REF(spritedataref)) > (MAXWPNS-1) )
13645 {
13646 Z_scripterrlog("Invalid Sprite ID passed to spritedata->FlashCSet: %d\n", GET_REF(spritedataref));
13647 }
13648 else
13649 {
13650 wpnsbuf[GET_REF(spritedataref)].csets &= 0x0F;
13651 wpnsbuf[GET_REF(spritedataref)].csets |= vbound((value / 10000),0,15)<<4;
13652 }
13653 break;
13654 }
13655 case SPRITEDATAFRAMES: SET_SPRITEDATA_VAR_BYTE(frames, "Frames"); break;
13656 case SPRITEDATASPEED: SET_SPRITEDATA_VAR_BYTE(speed, "Speed"); break;
13657 case SPRITEDATATYPE: SET_SPRITEDATA_VAR_BYTE(type, "Type"); break;
13658
13659 ///----------------------------------------------------------------------------------------------------//
13660 //mapdata m-> Variables
13661 //mapdata m-> Variables
13662
13663 #define SET_MAPDATA_VAR_INT32(member) \
13664 { \
13665 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13666 { \
13667 m->member = vbound((value / 10000),-214747,214747); \
13668 } \
13669 break; \
13670 } \
13671
13672 #define SET_MAPDATA_VAR_INT16(member) \
13673 { \
13674 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13675 { \
13676 m->member = vbound((value / 10000),0,32767); \
13677 } \
13678 break; \
13679 } \
13680
13681 #define SET_MAPDATA_VAR_BYTE(member) \
13682 { \
13683 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13684 { \
13685 m->member = vbound((value / 10000),0,255); \
13686 } \
13687 break; \
13688 } \
13689
13690 #define SET_MAPDATA_VAR_INDEX32(member, indexbound) \
13691 { \
13692 int32_t indx = GET_D(rINDEX) / 10000; \
13693 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
13694 { \
13695 } \
13696 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13697 { \
13698 m->member[indx] = vbound((value / 10000),-214747,214747); \
13699 } \
13700 break; \
13701 } \
13702
13703 #define SET_MAPDATA_VAR_INDEX16(member, indexbound) \
13704 { \
13705 int32_t indx = GET_D(rINDEX) / 10000; \
13706 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
13707 { \
13708 } \
13709 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13710 { \
13711 m->member[indx] = vbound((value / 10000),-32767,32767); \
13712 } \
13713 break; \
13714 } \
13715
13716 #define SET_MAPDATA_BYTE_INDEX(member, indexbound) \
13717 { \
13718 int32_t indx = GET_D(rINDEX) / 10000; \
13719 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
13720 { \
13721 } \
13722 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13723 { \
13724 m->member[indx] = vbound((value / 10000),0,255); \
13725 } \
13726 break; \
13727 }\
13728
13729 #define SET_MAPDATA_LAYER_INDEX(member, indexbound) \
13730 { \
13731 int32_t indx = GET_D(rINDEX) / 10000; \
13732 if ( FFCore.quest_format[vFFScript] < 11 ) ++indx; \
13733 if (BC::checkIndex(indx, 1, indexbound) != SH::_NoError) \
13734 { \
13735 } \
13736 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13737 { \
13738 m->member[indx-1] = vbound((value / 10000),0,255); \
13739 } \
13740 break; \
13741 } \
13742
13743 #define SET_MAPDATA_LAYERSCREEN_INDEX(member, indexbound) \
13744 { \
13745 int32_t indx = GET_D(rINDEX) / 10000; \
13746 if ( FFCore.quest_format[vFFScript] < 11 ) ++indx; \
13747 int32_t scrn_id = value/10000; \
13748 if (BC::checkIndex(indx, 1, indexbound) != SH::_NoError) \
13749 { \
13750 } \
13751 else if ( scrn_id > MAPSCRS ) \
13752 { \
13753 Z_scripterrlog("Script attempted to use a mapdata->LayerScreen[%d].\n",scrn_id); \
13754 Z_scripterrlog("Valid Screen values are (0) through (%d).\n",MAPSCRS); \
13755 } \
13756 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13757 { \
13758 m->member[indx-1] = vbound((scrn_id),0,MAPSCRS); \
13759 } \
13760 break; \
13761 }\
13762
13763 #define SET_MAPDATA_BOOL_INDEX(member, indexbound) \
13764 { \
13765 int32_t indx = GET_D(rINDEX) / 10000; \
13766 if (BC::checkIndex(indx, 0, indexbound) != SH::_NoError) \
13767 { \
13768 } \
13769 else if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13770 { \
13771 m->member[indx] =( (value/10000) ? 1 : 0 ); \
13772 } \
13773 break; \
13774 } \
13775
13776
13777 #define SET_FFC_MAPDATA_BOOL_INDEX(member, indexbound) \
13778 { \
13779 int32_t index = GET_D(rINDEX) / 10000; \
13780 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index)) \
13781 { \
13782 handle.ffc->member =( (value/10000) ? 1 : 0 ); \
13783 } \
13784 break; \
13785 } \
13786
13787 #define SET_MAPDATA_FLAG(member) \
13788 { \
13789 int32_t flag = (value/10000); \
13790 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref))) \
13791 { \
13792 if ( flag != 0 ) \
13793 { \
13794 m->member|=flag; \
13795 } \
13796 else m->.member|= ~flag; \
13797 } \
13798 break; \
13799 } \
13800
13801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 case MAPDATAVALID: SET_MAPDATA_VAR_BYTE(valid); break; //b
13802 case MAPDATAGUY: SET_MAPDATA_VAR_BYTE(guy); break; //b
13803 case MAPDATASTRING: SET_MAPDATA_VAR_INT32(str); break; //w
13804 case MAPDATAROOM: SET_MAPDATA_VAR_BYTE(room); break; //b
13805 case MAPDATAITEM:
13806 {
13807 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13808 {
13809 auto v = vbound((value / 10000),-1,255);
13810 if(v > -1)
13811 m->item = v;
13812 m->hasitem = v > -1;
13813 }
13814 break;
13815 }
13816 case MAPDATAREGIONID:
13817 {
13818 370 int region_id = value / 10000;
13819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 370 times.
370 if (BC::checkBounds(region_id, 0, 9) != SH::_NoError)
13820 break;
13821
13822 370 auto result = decode_mapdata_ref(GET_REF(mapdataref));
13823
1/2
✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
370 if (result.scr)
13824 {
13825
1/2
✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
370 if (result.type == mapdata_type::CanonicalScreen)
13826 {
13827 370 Regions[result.scr->map].set_region_id(result.screen, region_id);
13828 370 }
13829 else
13830 {
13831 scripting_log_error_with_context("This may only be set for canonical screens");
13832 }
13833 370 }
13834 else
13835 {
13836 scripting_log_error_with_context("mapdata pointer is either invalid or uninitialised");
13837 }
13838 370 break;
13839 }
13840 case MAPDATAHASITEM: SET_MAPDATA_VAR_BYTE(hasitem); break; //b
13841 case MAPDATADOORCOMBOSET: SET_MAPDATA_VAR_INT32(door_combo_set); break; //w
13842 case MAPDATAWARPRETURNC: SET_MAPDATA_VAR_INT32(warpreturnc); break; //w
13843 case MAPDATASTAIRX: SET_MAPDATA_VAR_BYTE(stairx); break; //b
13844 case MAPDATASTAIRY: SET_MAPDATA_VAR_BYTE(stairy); break; //b
13845 case MAPDATAITEMX: SET_MAPDATA_VAR_BYTE(itemx); break; //itemx
13846 case MAPDATAITEMY: SET_MAPDATA_VAR_BYTE(itemy); break; //itemy
13847 case MAPDATACOLOUR: SET_MAPDATA_VAR_INT32(color); break; //w
13848 case MAPDATAENEMYFLAGS: SET_MAPDATA_VAR_BYTE(flags11); break; //b
13849 case MAPDATAEXITDIR: SET_MAPDATA_VAR_BYTE(exitdir); break; //b
13850 case MAPDATAPATTERN: SET_MAPDATA_VAR_BYTE(pattern); break; //b
13851 case MAPDATAWARPARRIVALX: SET_MAPDATA_VAR_BYTE(warparrivalx); break; //b
13852 case MAPDATAWARPARRIVALY: SET_MAPDATA_VAR_BYTE(warparrivaly); break; //b
13853
13854 case MAPDATASIDEWARPINDEX: SET_MAPDATA_VAR_BYTE(sidewarpindex); break; //b
13855 case MAPDATAUNDERCOMBO: SET_MAPDATA_VAR_INT32(undercombo); break; //w
13856 case MAPDATAUNDERCSET: SET_MAPDATA_VAR_BYTE(undercset); break; //b
13857 case MAPDATACATCHALL: SET_MAPDATA_VAR_INT32(catchall); break; //W
13858
13859 case MAPDATACSENSITIVE: SET_MAPDATA_VAR_BYTE(csensitive); break; //B
13860 case MAPDATANORESET: SET_MAPDATA_VAR_INT32(noreset); break; //W
13861 case MAPDATANOCARRY: SET_MAPDATA_VAR_INT32(nocarry); break; //W
13862 case MAPDATATIMEDWARPTICS: SET_MAPDATA_VAR_INT32(timedwarptics); break; //W
13863 case MAPDATANEXTMAP: SET_MAPDATA_VAR_BYTE(nextmap); break; //B
13864 case MAPDATANEXTSCREEN: SET_MAPDATA_VAR_BYTE(nextscr); break; //B
13865 case MAPDATAVIEWX: break;//SET_MAPDATA_VAR_INT32(viewX, "ViewX"); break; //W
13866 case MAPDATASCRIPT:
13867 {
13868 auto result = decode_mapdata_ref(GET_REF(mapdataref));
13869 if (result.scr)
13870 {
13871 if (result.current())
13872 {
13873 if (get_qr(qr_CLEARINITDONSCRIPTCHANGE))
13874 {
13875 for (int q=0; q<8; q++)
13876 result.scr->screeninitd[q] = 0;
13877 }
13878
13879 on_reassign_script_engine_data(ScriptType::Screen, ri->screenref);
13880 }
13881
13882 result.scr->script = vbound(value/10000, 0, NUMSCRIPTSCREEN-1);
13883 }
13884 else
13885 {
13886 Z_scripterrlog("Script attempted to use a mapdata->%s on an invalid pointer\n","Script");
13887 }
13888 break;
13889 }
13890 case MAPDATAVIEWY: break;//SET_MAPDATA_VAR_INT32(viewY, "ViewY"); break; //W
13891 case MAPDATASCREENWIDTH: break;//SET_MAPDATA_VAR_BYTE(scrWidth, "Width"); break; //B
13892 case MAPDATASCREENHEIGHT: break;//SET_MAPDATA_VAR_BYTE(scrHeight, "Height"); break; //B
13893 case MAPDATAENTRYX: SET_MAPDATA_VAR_BYTE(entry_x); break; //B
13894 case MAPDATAENTRYY: SET_MAPDATA_VAR_BYTE(entry_y); break; //B
13895
13896 //Number of ffcs that are in use (have valid data
13897 case MAPDATANUMFF:
13898 {
13899 break;
13900 }
13901
13902 case MAPDATAINTID:
13903 {
13904 9 int32_t index = (GET_D(rINDEX)/10000);
13905 9 int32_t dindex = GET_D(rINDEX2)/10000;
13906
13907
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (BC::checkBounds(dindex, 0, 7) != SH::_NoError)
13908 break;
13909
13910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (auto handle = ResolveMapdataFFC(ri->mapdataref, index))
13911 9 handle.ffc->initd[dindex] = value;
13912 9 break;
13913 }
13914
13915 case MAPDATASCRIPTENTRY:
13916 {
13917 Z_scripterrlog("Unimplemented: %s\n", "ScriptEntry");
13918 }
13919 break;
13920 case MAPDATASCRIPTOCCUPANCY:
13921 {
13922 Z_scripterrlog("Unimplemented: %s\n", "ScriptOccupancy");
13923 }
13924 break;
13925 case MAPDATASCRIPTEXIT:
13926 {
13927 Z_scripterrlog("Unimplemented: %s\n", "ExitScript");
13928 }
13929 break;
13930
13931 case MAPDATAOCEANSFX:
13932 {
13933 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13934 {
13935 int32_t v = vbound(value/10000, 0, 255);
13936 if(m == hero_scr && m->oceansfx != v)
13937 {
13938 stop_sfx(m->oceansfx);
13939 m->oceansfx = v;
13940 cont_sfx(m->oceansfx);
13941 }
13942 else m->oceansfx = v;
13943 }
13944 break;
13945 }
13946 case MAPDATABOSSSFX: SET_MAPDATA_VAR_BYTE(bosssfx); break; //B
13947 case MAPDATASECRETSFX: SET_MAPDATA_VAR_BYTE(secretsfx); break; //B
13948 case MAPDATAHOLDUPSFX: SET_MAPDATA_VAR_BYTE(holdupsfx); break; //B
13949 case MAPDATASCREENMIDI:
13950 {
13951 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13952 {
13953 m->screen_midi = vbound((value / 10000)-(MIDIOFFSET_MAPSCR-MIDIOFFSET_ZSCRIPT),-1,32767);
13954 }
13955 break;
13956 }
13957 case MAPDATA_GRAVITY_STRENGTH:
13958 {
13959 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13960 {
13961 m->screen_gravity = zslongToFix(value);
13962 }
13963 break;
13964 }
13965 case MAPDATA_TERMINAL_VELOCITY:
13966 {
13967 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13968 {
13969 m->screen_terminal_v = zslongToFix(value);
13970 }
13971 break;
13972 }
13973 case MAPDATALENSLAYER: SET_MAPDATA_VAR_BYTE(lens_layer); break; //B, OLD QUESTS ONLY?
13974
13975 case MAPDATASCRDATASIZE:
13976 {
13977 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13978 {
13979 int index = get_ref_map_index(GET_REF(mapdataref));
13980 if (index < 0) break;
13981
13982 game->scriptDataResize(index, value/10000);
13983 }
13984 break;
13985 }
13986 case MAPDATAGUYCOUNT:
13987 {
13988 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
13989 {
13990 int mi = get_mi(GET_REF(mapdataref));
13991 if(mi > -1)
13992 {
13993 game->guys[mi] = vbound(value/10000,10,0);
13994 break;
13995 }
13996 }
13997 break;
13998 }
13999 case MAPDATAEXDOOR:
14000 {
14001 if (mapscr *m = ResolveMapdataScr(GET_REF(mapdataref)))
14002 {
14003 int mi = get_mi(GET_REF(mapdataref));
14004 if(mi < 0) break;
14005 int dir = SH::read_stack(ri->sp+1) / 10000;
14006 int ind = SH::read_stack(ri->sp+0) / 10000;
14007 if(unsigned(dir) > 3)
14008 Z_scripterrlog("Invalid dir '%d' passed to 'mapdata->SetExDoor()'; must be 0-3\n", dir);
14009 else if(unsigned(ind) > 7)
14010 Z_scripterrlog("Invalid index '%d' passed to 'mapdata->SetExDoor()'; must be 0-7\n", ind);
14011 else
14012 set_xdoorstate_mi(mi, dir, ind);
14013 }
14014 break;
14015 }
14016
14017 ///----------------------------------------------------------------------------------------------------//
14018 //dmapdata dmd-> Variables
14019 case DMAPDATAMAP: //byte
14020 {
14021 DMaps[GET_REF(dmapdataref)].map = ((byte)(value / 10000)) - 1; break;
14022 }
14023 case DMAPDATALEVEL: //word
14024 {
14025 DMaps[GET_REF(dmapdataref)].level = ((word)(value / 10000)); break;
14026 }
14027 case DMAPDATAFLOOR: //byte
14028 {
14029 DMaps[GET_REF(dmapdataref)].floor = ((byte)(value / 10000)); break;
14030 }
14031 case DMAPDATAOFFSET: //char
14032 {
14033 DMaps[GET_REF(dmapdataref)].xoff = ((char)(value / 10000)); break;
14034 }
14035 case DMAPDATACOMPASS: //byte
14036 {
14037 DMaps[GET_REF(dmapdataref)].compass = ((byte)(value / 10000)); break;
14038 }
14039 case DMAPDATAPALETTE: //word
14040 {
14041 168468 DMaps[GET_REF(dmapdataref)].color= ((word)(value / 10000));
14042
2/2
✓ Branch 0 taken 168129 times.
✓ Branch 1 taken 339 times.
168468 if(ri->dmapdataref == cur_dmap)
14043 {
14044 339 loadlvlpal(DMaps[GET_REF(dmapdataref)].color);
14045 339 currcset = DMaps[GET_REF(dmapdataref)].color;
14046 339 }
14047 168468 break;
14048 }
14049 case DMAPDATAMIDI: //byte
14050 {
14051 DMaps[GET_REF(dmapdataref)].midi = ((byte)((value / 10000)+MIDIOFFSET_DMAP)); break;
14052 }
14053 case DMAPDATA_GRAVITY_STRENGTH:
14054 {
14055 DMaps[GET_REF(dmapdataref)].dmap_gravity = zslongToFix(value);
14056 break;
14057 }
14058 case DMAPDATA_TERMINAL_VELOCITY:
14059 {
14060 DMaps[GET_REF(dmapdataref)].dmap_terminal_v = zslongToFix(value);
14061 break;
14062 }
14063 case DMAPDATACONTINUE: //byte
14064 {
14065 DMaps[GET_REF(dmapdataref)].cont = ((byte)(value / 10000)); break;
14066 }
14067 case DMAPDATATYPE: //byte
14068 {
14069 DMaps[GET_REF(dmapdataref)].type = (((byte)(value / 10000))&dmfTYPE) | (DMaps[GET_REF(dmapdataref)].type&~dmfTYPE); break;
14070 }
14071 case DMAPSCRIPT: //byte
14072 {
14073 DMaps[GET_REF(dmapdataref)].script = vbound((value / 10000),0,NUMSCRIPTSDMAP-1);
14074 on_reassign_script_engine_data(ScriptType::DMap, ri->dmapdataref);
14075 break;
14076 }
14077 case DMAPDATASIDEVIEW: //byte, treat as bool
14078 {
14079 DMaps[GET_REF(dmapdataref)].sideview = ((value) ? 1 : 0); break;
14080 }
14081 case DMAPDATAMUISCTRACK: //byte
14082 {
14083 DMaps[GET_REF(dmapdataref)].tmusictrack= ((byte)(value / 10000)); break;
14084 }
14085 case DMAPDATASUBSCRA:
14086 {
14087 bool changed = DMaps[GET_REF(dmapdataref)].active_subscreen != ((byte)(value / 10000));
14088 DMaps[GET_REF(dmapdataref)].active_subscreen= ((byte)(value / 10000));
14089 if(changed&&ri->dmapdataref==cur_dmap)
14090 update_subscreens();
14091 break;
14092 }
14093 case DMAPDATASUBSCRP:
14094 {
14095 5120 bool changed = DMaps[GET_REF(dmapdataref)].passive_subscreen != ((byte)(value / 10000));
14096 5120 DMaps[GET_REF(dmapdataref)].passive_subscreen= ((byte)(value / 10000));
14097
3/4
✓ Branch 0 taken 5120 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 10 times.
5120 if(changed&&ri->dmapdataref==cur_dmap)
14098 10 update_subscreens();
14099 5120 break;
14100 }
14101 case DMAPDATASUBSCRO:
14102 {
14103 bool changed = DMaps[GET_REF(dmapdataref)].overlay_subscreen != ((byte)(value / 10000));
14104 DMaps[GET_REF(dmapdataref)].overlay_subscreen = ((byte)(value / 10000));
14105 if(changed&&ri->dmapdataref==cur_dmap)
14106 update_subscreens();
14107 break;
14108 }
14109 case DMAPDATAFLAGS: //int32_t
14110 {
14111 DMaps[GET_REF(dmapdataref)].flags = (value / 10000); break;
14112 }
14113 case DMAPDATAMIRRDMAP:
14114 {
14115 DMaps[GET_REF(dmapdataref)].mirrorDMap = vbound(value / 10000, -1, MAXDMAPS); break;
14116 }
14117 case DMAPDATALOOPSTART:
14118 {
14119 DMaps[GET_REF(dmapdataref)].tmusic_loop_start = value;
14120 if (ri->dmapdataref == cur_dmap)
14121 {
14122 if (FFCore.doing_dmap_enh_music(cur_dmap))
14123 {
14124 zcmusic_set_loop(zcmusic, double(DMaps[cur_dmap].tmusic_loop_start / 10000.0), double(DMaps[cur_dmap].tmusic_loop_end / 10000.0));
14125 }
14126 }
14127 break;
14128 }
14129 case DMAPDATALOOPEND:
14130 {
14131 DMaps[GET_REF(dmapdataref)].tmusic_loop_end = value;
14132 if (ri->dmapdataref == cur_dmap)
14133 {
14134 if (FFCore.doing_dmap_enh_music(cur_dmap))
14135 {
14136 zcmusic_set_loop(zcmusic, double(DMaps[cur_dmap].tmusic_loop_start / 10000.0), double(DMaps[cur_dmap].tmusic_loop_end / 10000.0));
14137 }
14138 }
14139 break;
14140 }
14141 case DMAPDATAXFADEIN:
14142 {
14143 DMaps[GET_REF(dmapdataref)].tmusic_xfade_in = (value / 10000);
14144 break;
14145 }
14146 case DMAPDATAXFADEOUT:
14147 {
14148 DMaps[GET_REF(dmapdataref)].tmusic_xfade_out = (value / 10000);
14149 if (DMaps[cur_dmap].tmusic[0]!=0 && strcmp(DMaps[GET_REF(dmapdataref)].tmusic, zcmusic->filename) == 0)
14150 {
14151 zcmusic->fadeoutframes = (value / 10000);
14152 }
14153 break;
14154 }
14155 case DMAPDATAINTROSTRINGID:
14156 {
14157 DMaps[GET_REF(dmapdataref)].intro_string_id = (value / 10000);
14158 break;
14159 }
14160 case MUSICUPDATECOND:
14161 {
14162 FFCore.music_update_cond = vbound(value / 10000, 0, 255);
14163 break;
14164 }
14165 case DMAPDATAASUBSCRIPT: //byte
14166 {
14167 DMaps[GET_REF(dmapdataref)].active_sub_script = vbound((value / 10000),0,NUMSCRIPTSDMAP-1);
14168 on_reassign_script_engine_data(ScriptType::ScriptedActiveSubscreen, ri->dmapdataref);
14169 break;
14170 }
14171 case DMAPDATAMAPSCRIPT: //byte
14172 {
14173 3450 DMaps[GET_REF(dmapdataref)].onmap_script = vbound((value / 10000),0,NUMSCRIPTSDMAP-1);
14174 3450 on_reassign_script_engine_data(ScriptType::OnMap, ri->dmapdataref);
14175 3450 break;
14176 }
14177 case DMAPDATAPSUBSCRIPT: //byte
14178 {
14179 FFScript::deallocateAllScriptOwned(ScriptType::ScriptedPassiveSubscreen, ri->dmapdataref);
14180 word val = vbound((value / 10000),0,NUMSCRIPTSDMAP-1);
14181 if (FFCore.doscript(ScriptType::ScriptedPassiveSubscreen) && ri->dmapdataref == cur_dmap && val == DMaps[GET_REF(dmapdataref)].passive_sub_script)
14182 break;
14183 DMaps[GET_REF(dmapdataref)].passive_sub_script = val;
14184 if(ri->dmapdataref == cur_dmap)
14185 {
14186 FFCore.doscript(ScriptType::ScriptedPassiveSubscreen) = val != 0;
14187 };
14188 break;
14189 }
14190
14191 ///----------------------------------------------------------------------------------------------------//
14192 //messagedata msgd-> Variables
14193
14194
14195 case MESSAGEDATANEXT: //W
14196 {
14197 42 int32_t ID = GET_REF(msgdataref);
14198
14199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if(BC::checkMessage(ID) != SH::_NoError)
14200 break;
14201 else
14202 42 MsgStrings[ID].nextstring = vbound((value/10000), 0, (msg_count-1));
14203 42 break;
14204 }
14205
14206 case MESSAGEDATATILE: //W
14207 {
14208 int32_t ID = GET_REF(msgdataref);
14209
14210 if(BC::checkMessage(ID) != SH::_NoError)
14211 break;
14212 else
14213 MsgStrings[ID].tile = vbound((value/10000), 0, (NEWMAXTILES));
14214 break;
14215 }
14216
14217 case MESSAGEDATACSET: //b
14218 {
14219 int32_t ID = GET_REF(msgdataref);
14220
14221 if(BC::checkMessage(ID) != SH::_NoError)
14222 break;
14223 else
14224 MsgStrings[ID].cset = ((byte)vbound((value/10000), 0, 15));
14225 break;
14226 }
14227 case MESSAGEDATATRANS: //BOOL
14228 {
14229 int32_t ID = GET_REF(msgdataref);
14230
14231 if(BC::checkMessage(ID) != SH::_NoError)
14232 break;
14233 else
14234 (MsgStrings[ID].trans) = ((value)?true:false);
14235 break;
14236 }
14237 case MESSAGEDATAFONT: //B
14238 {
14239 int32_t ID = GET_REF(msgdataref);
14240
14241 if(BC::checkMessage(ID) != SH::_NoError)
14242 break;
14243 else
14244 MsgStrings[ID].font = ((byte)vbound((value/10000), 0, 255));
14245 break;
14246 }
14247 case MESSAGEDATAX: //SHORT
14248 {
14249 36 int32_t ID = GET_REF(msgdataref);
14250
14251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if(BC::checkMessage(ID) != SH::_NoError)
14252 break;
14253 else
14254 36 MsgStrings[ID].x = ((int16_t)vbound((value/10000), SHRT_MIN, SHRT_MAX));
14255 36 break;
14256 }
14257 case MESSAGEDATAY: //SHORT
14258 {
14259 36 int32_t ID = GET_REF(msgdataref);
14260
14261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if(BC::checkMessage(ID) != SH::_NoError)
14262 break;
14263 else
14264 36 MsgStrings[ID].y = ((int16_t)vbound((value/10000), SHRT_MIN, SHRT_MAX));
14265 36 break;
14266 }
14267 case MESSAGEDATAW: //UNSIGNED SHORT
14268 {
14269 int32_t ID = GET_REF(msgdataref);
14270
14271 if(BC::checkMessage(ID) != SH::_NoError)
14272 break;
14273 else
14274 MsgStrings[ID].w = ((uint16_t)vbound((value/10000), 0, USHRT_MAX));
14275 break;
14276 }
14277 case MESSAGEDATAH: //UNSIGNED SHORT
14278 {
14279 int32_t ID = GET_REF(msgdataref);
14280
14281 if(BC::checkMessage(ID) != SH::_NoError)
14282 break;
14283 else
14284 MsgStrings[ID].h = ((uint16_t)vbound((value/10000), 0, USHRT_MAX));
14285 break;
14286 }
14287 case MESSAGEDATASFX: //BYTE
14288 {
14289 36 int32_t ID = GET_REF(msgdataref);
14290
14291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if(BC::checkMessage(ID) != SH::_NoError)
14292 break;
14293 else
14294 36 MsgStrings[ID].sfx = ((byte)vbound((value/10000), 0, 255));
14295 36 break;
14296 }
14297 case MESSAGEDATALISTPOS: //WORD
14298 {
14299 int32_t ID = GET_REF(msgdataref);
14300
14301 if(BC::checkMessage(ID) != SH::_NoError)
14302 break;
14303 else
14304 MsgStrings[ID].listpos = vbound((value/10000), 1, (msg_count-1));
14305 break;
14306 }
14307 case MESSAGEDATAVSPACE: //BYTE
14308 {
14309 int32_t ID = GET_REF(msgdataref);
14310
14311 if(BC::checkMessage(ID) != SH::_NoError)
14312 break;
14313 else
14314 MsgStrings[ID].vspace = ((byte)vbound((value/10000), 0, 255));
14315 break;
14316 }
14317 case MESSAGEDATAHSPACE: //BYTE
14318 {
14319 int32_t ID = GET_REF(msgdataref);
14320
14321 if(BC::checkMessage(ID) != SH::_NoError)
14322 break;
14323 else
14324 MsgStrings[ID].hspace = ((byte)vbound((value/10000), 0, 255));
14325 break;
14326 }
14327 case MESSAGEDATAFLAGS: //BYTE
14328 {
14329 int32_t ID = GET_REF(msgdataref);
14330
14331 if(BC::checkMessage(ID) != SH::_NoError)
14332 break;
14333 else
14334 MsgStrings[ID].stringflags = ((byte)vbound((value/10000), 0, 255));
14335 break;
14336 }
14337 case MESSAGEDATAPORTTILE: //INT
14338 {
14339 int32_t ID = GET_REF(msgdataref);
14340
14341 if(BC::checkMessage(ID) != SH::_NoError)
14342 break;
14343 else
14344 MsgStrings[ID].portrait_tile = vbound((value/10000), 0, (NEWMAXTILES));
14345 break;
14346 }
14347 case MESSAGEDATAPORTCSET: //BYTE
14348 {
14349 int32_t ID = GET_REF(msgdataref);
14350
14351 if(BC::checkMessage(ID) != SH::_NoError)
14352 break;
14353 else
14354 MsgStrings[ID].portrait_cset = ((byte)vbound((value/10000), 0, 15));
14355 break;
14356 }
14357 case MESSAGEDATAPORTX: //BYTE
14358 {
14359 int32_t ID = GET_REF(msgdataref);
14360
14361 if(BC::checkMessage(ID) != SH::_NoError)
14362 break;
14363 else
14364 MsgStrings[ID].portrait_x = ((byte)vbound((value/10000), 0, 255));
14365 break;
14366 }
14367 case MESSAGEDATAPORTY: //BYTE
14368 {
14369 int32_t ID = GET_REF(msgdataref);
14370
14371 if(BC::checkMessage(ID) != SH::_NoError)
14372 break;
14373 else
14374 MsgStrings[ID].portrait_y = ((byte)vbound((value/10000), 0, 255));
14375 break;
14376 }
14377 case MESSAGEDATAPORTWID: //BYTE
14378 {
14379 int32_t ID = GET_REF(msgdataref);
14380
14381 if(BC::checkMessage(ID) != SH::_NoError)
14382 break;
14383 else
14384 MsgStrings[ID].portrait_tw = ((byte)vbound((value/10000), 0, 16));
14385 break;
14386 }
14387 case MESSAGEDATAPORTHEI: //BYTE
14388 {
14389 int32_t ID = GET_REF(msgdataref);
14390
14391 if(BC::checkMessage(ID) != SH::_NoError)
14392 break;
14393 else
14394 MsgStrings[ID].portrait_th = ((byte)vbound((value/10000), 0, 14));
14395 break;
14396 }
14397
14398 ///----------------------------------------------------------------------------------------------------//
14399 //combodata cd-> Setter Variables
14400 //newcombo
14401 #define SET_COMBO_VAR_INT(member) \
14402 { \
14403 if(checkComboRef()) \
14404 { \
14405 screen_combo_modify_pre(GET_REF(combodataref)); \
14406 combobuf[GET_REF(combodataref)].member = vbound((value / 10000),0,214747); \
14407 screen_combo_modify_post(GET_REF(combodataref)); \
14408 \
14409 } \
14410 } \
14411
14412 #define SET_COMBO_VAR_DWORD(member) \
14413 { \
14414 if(checkComboRef()) \
14415 { \
14416 screen_combo_modify_pre(GET_REF(combodataref)); \
14417 combobuf[GET_REF(combodataref)].member = vbound((value / 10000),0,32767); \
14418 screen_combo_modify_post(GET_REF(combodataref)); \
14419 } \
14420 } \
14421
14422 #define SET_COMBO_VAR_BYTE(member) \
14423 { \
14424 if(checkComboRef()) \
14425 { \
14426 screen_combo_modify_pre(GET_REF(combodataref)); \
14427 combobuf[GET_REF(combodataref)].member = vbound((value / 10000),0,255); \
14428 screen_combo_modify_post(GET_REF(combodataref)); \
14429 } \
14430 } \
14431
14432 //comboclass
14433 #define SET_COMBOCLASS_VAR_INT(member) \
14434 { \
14435 if(checkComboRef()) \
14436 { \
14437 combo_class_buf[combobuf[GET_REF(combodataref)].type].member = vbound((value / 10000),0,214747); \
14438 } \
14439 } \
14440
14441 #define SET_COMBOCLASS_VAR_DWORD(member) \
14442 { \
14443 if(checkComboRef()) \
14444 { \
14445 combo_class_buf[combobuf[GET_REF(combodataref)].type].member = vbound((value / 10000),0,32767); \
14446 } \
14447 } \
14448
14449 #define SET_COMBOCLASS_VAR_BYTE(member) \
14450 { \
14451 if(checkComboRef()) \
14452 { \
14453 combo_class_buf[combobuf[GET_REF(combodataref)].type].member = vbound((value / 10000),0,255); \
14454 } \
14455 } \
14456
14457 #define SET_COMBOCLASS_BYTE_INDEX(member, indexbound) \
14458 { \
14459 int32_t indx = GET_D(rINDEX) / 10000; \
14460 if(!checkComboRef()) \
14461 { \
14462 } \
14463 else if ( indx < 0 || indx > indexbound ) \
14464 { \
14465 scripting_log_error_with_context("Invalid Array Index: {}", indx); \
14466 } \
14467 else \
14468 { \
14469 combo_class_buf[combobuf[GET_REF(combodataref)].type].member[indx] = vbound((value / 10000),0,255); \
14470 } \
14471 }
14472
14473 //NEWCOMBO STRUCT
14474 case COMBODTILE: SET_COMBO_VAR_INT(tile); break; //word
14475 case COMBODOTILE:
14476 {
14477
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (!checkComboRef()) break;
14478
14479 9 newcombo& cdata = combobuf[GET_REF(combodataref)];
14480 9 cdata.o_tile = vbound((value / 10000),0,NEWMAXTILES);
14481
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if(get_qr(qr_NEW_COMBO_ANIMATION))
14482 {
14483 9 cdata.tile = cdata.o_tile + ((1+cdata.skipanim)*cdata.cur_frame);
14484
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(int32_t rowoffset = TILEROW(cdata.tile)-TILEROW(cdata.o_tile))
14485 {
14486 cdata.tile += cdata.skipanimy * rowoffset * TILES_PER_ROW;
14487 }
14488 9 combo_caches::drawing.refresh(GET_REF(combodataref));
14489 9 }
14490 9 break;
14491 }
14492 case COMBODFRAME: SET_COMBO_VAR_BYTE(cur_frame); break; //char
14493 case COMBODACLK: SET_COMBO_VAR_BYTE(aclk); break; //char
14494 case COMBODATASCRIPT: SET_COMBO_VAR_DWORD(script); break; //word
14495 case COMBODASPEED: SET_COMBO_VAR_BYTE(speed); break; //char
14496 case COMBODFLIP: SET_COMBO_VAR_BYTE(flip); break; //char
14497 case COMBODWALK:
14498 {
14499 if (!checkComboRef()) break;
14500
14501 combobuf[GET_REF(combodataref)].walk &= ~0x0F;
14502 combobuf[GET_REF(combodataref)].walk |= (value / 10000)&0x0F;
14503 break;
14504 }
14505 case COMBODEFFECT:
14506 {
14507 if (!checkComboRef()) break;
14508
14509 combobuf[GET_REF(combodataref)].walk &= ~0xF0;
14510 combobuf[GET_REF(combodataref)].walk |= ((value / 10000)&0x0F)<<4;
14511 break;
14512 }
14513 case COMBODTYPE:
14514 {
14515 if (!checkComboRef()) break;
14516
14517 screen_combo_modify_pre(GET_REF(combodataref));
14518 combobuf[GET_REF(combodataref)].type = vbound((value / 10000),0,255);
14519 screen_combo_modify_post(GET_REF(combodataref));
14520 break;
14521 }
14522 case COMBODCSET:
14523 {
14524 if (!checkComboRef()) break;
14525
14526 screen_combo_modify_pre(GET_REF(combodataref));
14527 int8_t v = vbound(value, -8, 7);
14528 combobuf[GET_REF(combodataref)].csets &= ~0xF;
14529 combobuf[GET_REF(combodataref)].csets |= v;
14530 screen_combo_modify_post(GET_REF(combodataref));
14531 break;
14532 }
14533 case COMBODCSET2FLAGS:
14534 {
14535 if (!checkComboRef()) break;
14536
14537 screen_combo_modify_pre(GET_REF(combodataref));
14538 combobuf[GET_REF(combodataref)].csets &= 0xF;
14539 combobuf[GET_REF(combodataref)].csets |= (value&0xF)<<4;
14540 screen_combo_modify_post(GET_REF(combodataref));
14541 break;
14542 }
14543 case COMBODFOO: break; //W
14544 case COMBODFRAMES: SET_COMBO_VAR_BYTE(frames); break; //C
14545 case COMBODNEXTD: SET_COMBO_VAR_INT(nextcombo); break; //W
14546 case COMBODNEXTC: SET_COMBO_VAR_BYTE(nextcset); break; //C
14547 case COMBODFLAG: SET_COMBO_VAR_BYTE(flag); break; //C
14548 case COMBODSKIPANIM: SET_COMBO_VAR_BYTE(skipanim); break; //C
14549 case COMBODNEXTTIMER: SET_COMBO_VAR_DWORD(nexttimer); break; //W
14550 case COMBODAKIMANIMY: SET_COMBO_VAR_BYTE(skipanimy); break; //C
14551 case COMBODANIMFLAGS: SET_COMBO_VAR_BYTE(animflags); break; //C
14552 case COMBODUSRFLAGS: SET_COMBO_VAR_INT(usrflags); break; //LONG
14553 case COMBODTRIGGERITEM:
14554 {
14555 if (!checkComboRef()) break;
14556
14557 if(auto* trig = get_first_combo_trigger())
14558 trig->triggeritem = vbound(value/10000,0,255);
14559 break;
14560 }
14561 case COMBODTRIGGERTIMER:
14562 {
14563 if (!checkComboRef()) break;
14564
14565 screen_combo_modify_pre(GET_REF(combodataref));
14566 if(auto* trig = get_first_combo_trigger())
14567 trig->trigtimer = vbound(value/10000,0,65535);
14568 screen_combo_modify_post(GET_REF(combodataref));
14569 break;
14570 }
14571 case COMBODTRIGGERSFX:
14572 {
14573 if (!checkComboRef()) break;
14574
14575 if(auto* trig = get_first_combo_trigger())
14576 trig->trigsfx = vbound(value/10000,0,255);
14577 break;
14578 }
14579 case COMBODTRIGGERCHANGECMB:
14580 {
14581 if (!checkComboRef()) break;
14582
14583 if(auto* trig = get_first_combo_trigger())
14584 trig->trigchange = vbound(value/10000,-65535,65535);
14585 break;
14586 }
14587 case COMBODTRIGGERPROX:
14588 {
14589 if (!checkComboRef()) break;
14590
14591 if(auto* trig = get_first_combo_trigger())
14592 trig->trigprox = vbound(value/10000,0,65535);
14593 break;
14594 }
14595 case COMBODTRIGGERLIGHTBEAM:
14596 {
14597 if (!checkComboRef()) break;
14598
14599 if(auto* trig = get_first_combo_trigger())
14600 trig->triglbeam = vbound(value/10000,0,32);
14601 break;
14602 }
14603 case COMBODTRIGGERCTR:
14604 {
14605 if (!checkComboRef()) break;
14606
14607 if(auto* trig = get_first_combo_trigger())
14608 trig->trigctr = vbound(value/10000, sscMIN, MAX_COUNTERS-1);
14609 break;
14610 }
14611 case COMBODTRIGGERCTRAMNT:
14612 {
14613 if (!checkComboRef()) break;
14614
14615 if(auto* trig = get_first_combo_trigger())
14616 trig->trigctramnt = vbound(value/10000, -65535, 65535);
14617 break;
14618 }
14619
14620 case COMBODTRIGGERCOOLDOWN:
14621 {
14622 if (!checkComboRef()) break;
14623
14624 if(auto* trig = get_first_combo_trigger())
14625 trig->trigcooldown = vbound(value/10000, 0, 255);
14626 break;
14627 }
14628 case COMBODTRIGGERCOPYCAT:
14629 {
14630 if (!checkComboRef()) break;
14631
14632 if(auto* trig = get_first_combo_trigger())
14633 trig->trigcopycat = vbound(value/10000, 0, 255);
14634 break;
14635 }
14636 case COMBODTRIGITEMPICKUP:
14637 {
14638 const int32_t allowed_pflags = ipHOLDUP | ipTIMER | ipSECRETS | ipCANGRAB;
14639 if (!checkComboRef()) break;
14640
14641 if(auto* trig = get_first_combo_trigger())
14642 trig->spawnip = (value/10000)&allowed_pflags;
14643 break;
14644 }
14645 case COMBODTRIGEXSTATE:
14646 {
14647 if (!checkComboRef()) break;
14648
14649 if(auto* trig = get_first_combo_trigger())
14650 trig->exstate = vbound(value/10000, -1, 31);
14651 break;
14652 }
14653 case COMBODTRIGEXDOORDIR:
14654 {
14655 if (!checkComboRef()) break;
14656
14657 if(auto* trig = get_first_combo_trigger())
14658 trig->exdoor_dir = vbound(value/10000, -1, 3);
14659 break;
14660 }
14661 case COMBODTRIGEXDOORIND:
14662 {
14663 if (!checkComboRef()) break;
14664
14665 if(auto* trig = get_first_combo_trigger())
14666 trig->exdoor_ind = vbound(value/10000, 0, 7);
14667 break;
14668 }
14669 case COMBODTRIGSPAWNENEMY:
14670 {
14671 if (!checkComboRef()) break;
14672
14673 if(auto* trig = get_first_combo_trigger())
14674 trig->spawnenemy = vbound(value/10000, 0, 511);
14675 break;
14676 }
14677 case COMBODTRIGSPAWNITEM:
14678 {
14679 if (!checkComboRef()) break;
14680
14681 if(auto* trig = get_first_combo_trigger())
14682 trig->spawnitem = vbound(value/10000, -255, 255);
14683 break;
14684 }
14685 case COMBODTRIGCSETCHANGE:
14686 {
14687 if (!checkComboRef()) break;
14688
14689 if(auto* trig = get_first_combo_trigger())
14690 trig->trigcschange = vbound(value/10000, -15, 15);
14691 break;
14692 }
14693 case COMBODTRIGLITEMS:
14694 {
14695 if (!checkComboRef()) break;
14696
14697 if(auto* trig = get_first_combo_trigger())
14698 trig->trig_levelitems = (value/10000)&LI_ALL;
14699 break;
14700 }
14701 case COMBODTRIGDMAPLVL:
14702 {
14703 if (!checkComboRef()) break;
14704
14705 if(auto* trig = get_first_combo_trigger())
14706 trig->trigdmlevel = vbound(value/10000, -1, MAXLEVELS-1);
14707 break;
14708 }
14709 case COMBODTRIGTINTR:
14710 {
14711 if (!checkComboRef()) break;
14712
14713 if(auto* trig = get_first_combo_trigger())
14714 trig->trigtint[0] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
14715 break;
14716 }
14717 case COMBODTRIGTINTG:
14718 {
14719 if (!checkComboRef()) break;
14720
14721 if(auto* trig = get_first_combo_trigger())
14722 trig->trigtint[1] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
14723 break;
14724 }
14725 case COMBODTRIGTINTB:
14726 {
14727 if (!checkComboRef()) break;
14728
14729 if(auto* trig = get_first_combo_trigger())
14730 trig->trigtint[2] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
14731 break;
14732 }
14733 case COMBODTRIGLVLPAL:
14734 {
14735 if (!checkComboRef()) break;
14736
14737 if(auto* trig = get_first_combo_trigger())
14738 trig->triglvlpalette = vbound(value/10000, -1, 512);
14739 break;
14740 }
14741 case COMBODTRIGBOSSPAL:
14742 {
14743 if (!checkComboRef()) break;
14744
14745 if(auto* trig = get_first_combo_trigger())
14746 trig->trigbosspalette = vbound(value/10000, -1, 29);
14747 break;
14748 }
14749 case COMBODTRIGQUAKETIME:
14750 {
14751 if (!checkComboRef()) break;
14752
14753 if(auto* trig = get_first_combo_trigger())
14754 trig->trigquaketime = zc_max(value/10000, -1);
14755 break;
14756 }
14757 case COMBODTRIGWAVYTIME:
14758 {
14759 if (!checkComboRef()) break;
14760
14761 if(auto* trig = get_first_combo_trigger())
14762 trig->trigwavytime = zc_max(value/10000, -1);
14763 break;
14764 }
14765 case COMBODTRIGSWORDJINX:
14766 {
14767 if (!checkComboRef()) break;
14768
14769 if(auto* trig = get_first_combo_trigger())
14770 trig->trig_swjinxtime = zc_max(value/10000, -2);
14771 break;
14772 }
14773 case COMBODTRIGITEMJINX:
14774 {
14775 if (!checkComboRef()) break;
14776
14777 if(auto* trig = get_first_combo_trigger())
14778 trig->trig_itmjinxtime = zc_max(value/10000, -2);
14779 break;
14780 }
14781 case COMBODTRIGSHIELDJINX:
14782 {
14783 if (!checkComboRef()) break;
14784
14785 else if(auto* trig = get_first_combo_trigger())
14786 trig->trig_shieldjinxtime = zc_max(value / 10000, -2);
14787 break;
14788 }
14789 case COMBODTRIGSTUN:
14790 {
14791 if (!checkComboRef()) break;
14792
14793 if(auto* trig = get_first_combo_trigger())
14794 trig->trig_stuntime = zc_max(value/10000, -2);
14795 break;
14796 }
14797 case COMBODTRIGBUNNY:
14798 {
14799 if (!checkComboRef()) break;
14800
14801 if(auto* trig = get_first_combo_trigger())
14802 trig->trig_bunnytime = zc_max(value/10000, -2);
14803 break;
14804 }
14805 case COMBODTRIGPUSHTIME:
14806 {
14807 if (!checkComboRef()) break;
14808
14809 if(auto* trig = get_first_combo_trigger())
14810 trig->trig_pushtime = vbound(value/10000, 0, 255);
14811 break;
14812 }
14813 case COMBODLIFTGFXCOMBO:
14814 {
14815 if (!checkComboRef()) break;
14816
14817 combobuf[GET_REF(combodataref)].liftcmb = vbound(value/10000, 0, MAXCOMBOS);
14818 break;
14819 }
14820 case COMBODLIFTGFXCCSET:
14821 {
14822 if (!checkComboRef()) break;
14823
14824 combobuf[GET_REF(combodataref)].liftcs = vbound(value/10000, 0, 13);
14825 break;
14826 }
14827 case COMBODLIFTUNDERCMB:
14828 {
14829 if (!checkComboRef()) break;
14830
14831 combobuf[GET_REF(combodataref)].liftundercmb = vbound(value/10000, 0, MAXCOMBOS);
14832 break;
14833 }
14834 case COMBODLIFTUNDERCS:
14835 {
14836 if (!checkComboRef()) break;
14837
14838 combobuf[GET_REF(combodataref)].liftundercs = vbound(value/10000, 0, 13);
14839 break;
14840 }
14841 case COMBODLIFTDAMAGE:
14842 {
14843 if (!checkComboRef()) break;
14844
14845 combobuf[GET_REF(combodataref)].liftdmg = vbound(value/10000, 0, 255);
14846 break;
14847 }
14848 case COMBODLIFTLEVEL:
14849 {
14850 if (!checkComboRef()) break;
14851
14852 combobuf[GET_REF(combodataref)].liftlvl = vbound(value/10000, 0, 255);
14853 break;
14854 }
14855 case COMBODLIFTITEM:
14856 {
14857 if (!checkComboRef()) break;
14858
14859 combobuf[GET_REF(combodataref)].liftitm = vbound(value/10000, 0, 255);
14860 break;
14861 }
14862 case COMBODLIFTGFXTYPE:
14863 {
14864 if (!checkComboRef()) break;
14865
14866 combobuf[GET_REF(combodataref)].liftgfx = vbound(value/10000, 0, 2);
14867 break;
14868 }
14869 case COMBODLIFTGFXSPRITE:
14870 {
14871 if (!checkComboRef()) break;
14872
14873 combobuf[GET_REF(combodataref)].liftsprite = vbound(value/10000, 0, 255);
14874 break;
14875 }
14876 case COMBODLIFTSFX:
14877 {
14878 if (!checkComboRef()) break;
14879
14880 combobuf[GET_REF(combodataref)].liftsfx = vbound(value/10000, 0, 255);
14881 break;
14882 }
14883 case COMBODLIFTBREAKSPRITE:
14884 {
14885 if (!checkComboRef()) break;
14886
14887 combobuf[GET_REF(combodataref)].liftbreaksprite = vbound(value/10000, -4, 255);
14888 break;
14889 }
14890 case COMBODLIFTBREAKSFX:
14891 {
14892 if (!checkComboRef()) break;
14893
14894 combobuf[GET_REF(combodataref)].liftbreaksfx = vbound(value/10000, 0, 255);
14895 break;
14896 }
14897 case COMBODLIFTHEIGHT:
14898 {
14899 if (!checkComboRef()) break;
14900
14901 combobuf[GET_REF(combodataref)].lifthei = vbound(value/10000, 0, 255);
14902 break;
14903 }
14904 case COMBODLIFTTIME:
14905 {
14906 if (!checkComboRef()) break;
14907
14908 combobuf[GET_REF(combodataref)].lifttime = vbound(value/10000, 0, 255);
14909 break;
14910 }
14911 case COMBODLIFTLIGHTRAD:
14912 {
14913 if (!checkComboRef()) break;
14914
14915 combobuf[GET_REF(combodataref)].lift_weap_data.light_rads[WPNSPR_BASE] = vbound(value/10000, 0, 255);
14916 break;
14917 }
14918 case COMBODLIFTLIGHTSHAPE:
14919 {
14920 if (!checkComboRef()) break;
14921
14922 combobuf[GET_REF(combodataref)].lift_weap_data.glow_shape = vbound(value/10000, 0, 2);
14923 break;
14924 }
14925 case COMBODLIFTWEAPONITEM:
14926 {
14927 if (!checkComboRef()) break;
14928
14929 combobuf[GET_REF(combodataref)].lift_parent_item = vbound(value/10000, 0, 255);
14930 break;
14931 }
14932 case COMBODTRIGGERLSTATE:
14933 {
14934 if (!checkComboRef()) break;
14935
14936 if(auto* trig = get_first_combo_trigger())
14937 trig->trig_lstate = vbound(value/10000, 0, 31);
14938 break;
14939 }
14940 case COMBODTRIGGERGSTATE:
14941 {
14942 if (!checkComboRef()) break;
14943
14944 if(auto* trig = get_first_combo_trigger())
14945 trig->trig_gstate = vbound(value/10000, 0, 255);
14946 break;
14947 }
14948 case COMBODTRIGGERGROUP:
14949 {
14950 if (!checkComboRef()) break;
14951
14952 if(auto* trig = get_first_combo_trigger())
14953 trig->trig_group = vbound(value/10000, 0, 255);
14954 break;
14955 }
14956 case COMBODTRIGGERGROUPVAL:
14957 {
14958 if (!checkComboRef()) break;
14959
14960 if(auto* trig = get_first_combo_trigger())
14961 trig->trig_group_val = vbound(value/10000, 0, 65535);
14962 break;
14963 }
14964 case COMBODTRIGGERGTIMER:
14965 {
14966 if (!checkComboRef()) break;
14967
14968 if(auto* trig = get_first_combo_trigger())
14969 trig->trig_statetime = vbound(value/10000, 0, 214748);
14970 break;
14971 }
14972 case COMBODTRIGGERGENSCRIPT:
14973 {
14974 if (!checkComboRef()) break;
14975
14976 if(auto* trig = get_first_combo_trigger())
14977 trig->trig_genscr = vbound(value/10000, 0, 65535);
14978 break;
14979 }
14980 case COMBODTRIGGERLEVEL:
14981 {
14982 if (!checkComboRef()) break;
14983
14984 if(auto* trig = get_first_combo_trigger())
14985 trig->triggerlevel = vbound(value/10000, 0, 214747);
14986 break;
14987 }
14988 case COMBODNUMTRIGGERS:
14989 {
14990 if(checkComboRef())
14991 combobuf[GET_REF(combodataref)].triggers.resize(vbound(value / 10000, 0, MAX_COMBO_TRIGGERS));
14992 break;
14993 }
14994 case COMBODONLYGEN:
14995 {
14996 if(checkComboRef())
14997 combobuf[GET_REF(combodataref)].only_gentrig = value != 0 ? 1 : 0;
14998 break;
14999 }
15000 case COMBOD_Z_HEIGHT:
15001 {
15002 if(checkComboRef())
15003 combobuf[GET_REF(combodataref)].z_height = zslongToFix(value);
15004 break;
15005 }
15006 case COMBOD_Z_STEP_HEIGHT:
15007 {
15008 if(checkComboRef())
15009 combobuf[GET_REF(combodataref)].z_step_height = zslongToFix(zc_max(0,value));
15010 break;
15011 }
15012 case COMBOD_DIVE_UNDER_LEVEL:
15013 {
15014 if(checkComboRef())
15015 combobuf[GET_REF(combodataref)].dive_under_level = (byte)vbound(value / 10000, 0, 255);
15016 break;
15017 }
15018
15019
15020
15021
15022 //COMBOCLASS STRUCT
15023 //case COMBODNAME: //CHAR[64], STRING
15024 case COMBODBLOCKNPC: SET_COMBOCLASS_VAR_BYTE(block_enemies); break; //C
15025 case COMBODBLOCKHOLE: SET_COMBOCLASS_VAR_BYTE(block_hole); break; //C
15026 case COMBODBLOCKTRIG: SET_COMBOCLASS_VAR_BYTE(block_trigger); break; //C
15027 // Note: not used?
15028 case COMBODBLOCKWEAPON: SET_COMBOCLASS_BYTE_INDEX(block_weapon, 32); break; //C, 32 INDICES
15029 case COMBODCONVXSPEED: SET_COMBOCLASS_VAR_DWORD(conveyor_x_speed); break; //SHORT
15030 case COMBODCONVYSPEED: SET_COMBOCLASS_VAR_DWORD(conveyor_y_speed); break; //SHORT
15031 case COMBODSPAWNNPC: SET_COMBOCLASS_VAR_DWORD(create_enemy); break; //W
15032 case COMBODSPAWNNPCWHEN: SET_COMBOCLASS_VAR_BYTE(create_enemy_when); break; //C
15033 case COMBODSPAWNNPCCHANGE: SET_COMBOCLASS_VAR_INT(create_enemy_change); break; //LONG
15034 case COMBODDIRCHANGETYPE: SET_COMBOCLASS_VAR_BYTE(directional_change_type); break; //C
15035 case COMBODDISTANCECHANGETILES: SET_COMBOCLASS_VAR_INT(distance_change_tiles); break; //LONG
15036 case COMBODDIVEITEM: SET_COMBOCLASS_VAR_DWORD(dive_item); break; //SHORT
15037 case COMBODDOCK: SET_COMBOCLASS_VAR_BYTE(dock); break; //C
15038 case COMBODFAIRY: SET_COMBOCLASS_VAR_BYTE(fairy); break; //C
15039 case COMBODFFATTRCHANGE: SET_COMBOCLASS_VAR_BYTE(ff_combo_attr_change); break; //C
15040 case COMBODFOORDECOTILE: SET_COMBOCLASS_VAR_INT(foot_decorations_tile); break; //LONG
15041 case COMBODFOORDECOTYPE: SET_COMBOCLASS_VAR_BYTE(foot_decorations_type); break; //C
15042 case COMBODHOOKSHOTPOINT: SET_COMBOCLASS_VAR_BYTE(hookshot_grab_point); break; //C
15043 case COMBODLADDERPASS: SET_COMBOCLASS_VAR_BYTE(ladder_pass); break; //C
15044 case COMBODLOCKBLOCK: SET_COMBOCLASS_VAR_BYTE(lock_block_type); break; //C
15045 case COMBODLOCKBLOCKCHANGE: SET_COMBOCLASS_VAR_INT(lock_block_change); break; //LONG
15046 case COMBODMAGICMIRROR: SET_COMBOCLASS_VAR_BYTE(magic_mirror_type); break; //C
15047 case COMBODMODHPAMOUNT: SET_COMBOCLASS_VAR_DWORD(modify_hp_amount); break; //SHORT
15048 case COMBODMODHPDELAY: SET_COMBOCLASS_VAR_BYTE(modify_hp_delay); break; //C
15049 case COMBODMODHPTYPE: SET_COMBOCLASS_VAR_BYTE(modify_hp_type); break; //C
15050 case COMBODNMODMPAMOUNT: SET_COMBOCLASS_VAR_DWORD(modify_mp_amount); break; //SHORT
15051 case COMBODMODMPDELAY: SET_COMBOCLASS_VAR_BYTE(modify_mp_delay); break; //C
15052 case COMBODMODMPTYPE: SET_COMBOCLASS_VAR_BYTE(modify_mp_type); break; //C
15053 case COMBODNOPUSHBLOCK: SET_COMBOCLASS_VAR_BYTE(no_push_blocks); break; //C
15054 case COMBODOVERHEAD: SET_COMBOCLASS_VAR_BYTE(overhead); break; //C
15055 case COMBODPLACENPC: SET_COMBOCLASS_VAR_BYTE(place_enemy); break; //C
15056 case COMBODPUSHDIR: SET_COMBOCLASS_VAR_BYTE(push_direction); break; //C
15057 case COMBODPUSHWAIT: SET_COMBOCLASS_VAR_BYTE(push_wait); break; //C
15058 case COMBODPUSHHEAVY: SET_COMBOCLASS_VAR_BYTE(push_weight); break; //C
15059 case COMBODPUSHED: SET_COMBOCLASS_VAR_BYTE(pushed); break; //C
15060 case COMBODRAFT: SET_COMBOCLASS_VAR_BYTE(raft); break; //C
15061 case COMBODRESETROOM: SET_COMBOCLASS_VAR_BYTE(reset_room); break; //C
15062 case COMBODSAVEPOINTTYPE: SET_COMBOCLASS_VAR_BYTE(save_point_type); break; //C
15063 case COMBODSCREENFREEZETYPE: SET_COMBOCLASS_VAR_BYTE(screen_freeze_type); break; //C
15064 case COMBODSECRETCOMBO: SET_COMBOCLASS_VAR_BYTE(secret_combo); break; //C
15065 case COMBODSINGULAR: SET_COMBOCLASS_VAR_BYTE(singular); break; //C
15066 case COMBODSLOWWALK: SET_COMBOCLASS_VAR_BYTE(slow_movement); break; //C
15067 case COMBODSTATUETYPE: SET_COMBOCLASS_VAR_BYTE(statue_type); break; //C
15068 case COMBODSTEPTYPE: SET_COMBOCLASS_VAR_BYTE(step_type); break; //C
15069 case COMBODSTEPCHANGEINTO: SET_COMBOCLASS_VAR_INT(step_change_to); break; //LONG
15070 case COMBODSTRIKEWEAPONS: SET_COMBOCLASS_BYTE_INDEX(strike_weapons, 32); break; //BYTE, 32 INDICES.
15071 case COMBODSTRIKEREMNANTS: SET_COMBOCLASS_VAR_INT(strike_remnants); break; //LONG
15072 case COMBODSTRIKEREMNANTSTYPE: SET_COMBOCLASS_VAR_BYTE(strike_remnants_type); break; //C
15073 case COMBODSTRIKECHANGE: SET_COMBOCLASS_VAR_INT(strike_change); break; //LONG
15074 case COMBODSTRIKEITEM: SET_COMBOCLASS_VAR_DWORD(strike_item); break; //SHORT
15075 case COMBODTOUCHITEM: SET_COMBOCLASS_VAR_DWORD(touch_item); break; //SHORT
15076 case COMBODTOUCHSTAIRS: SET_COMBOCLASS_VAR_BYTE(touch_stairs); break; //C
15077 case COMBODTRIGGERTYPE: SET_COMBOCLASS_VAR_BYTE(trigger_type); break; //C
15078 case COMBODTRIGGERSENS: SET_COMBOCLASS_VAR_BYTE(trigger_sensitive); break; //C
15079 case COMBODWARPTYPE: SET_COMBOCLASS_VAR_BYTE(warp_type); break; //C
15080 case COMBODWARPSENS: SET_COMBOCLASS_VAR_BYTE(warp_sensitive); break; //C
15081 case COMBODWARPDIRECT: SET_COMBOCLASS_VAR_BYTE(warp_direct); break; //C
15082 case COMBODWARPLOCATION: SET_COMBOCLASS_VAR_BYTE(warp_location); break; //C
15083 case COMBODWATER: SET_COMBOCLASS_VAR_BYTE(water); break; //C
15084 case COMBODWHISTLE: SET_COMBOCLASS_VAR_BYTE(whistle); break; //C
15085 case COMBODWINGAME: SET_COMBOCLASS_VAR_BYTE(win_game); break; //C
15086 case COMBODBLOCKWPNLEVEL: SET_COMBOCLASS_VAR_BYTE(block_weapon_lvl); break; //C
15087
15088
15089
15090 ///----------------------------------------------------------------------------------------------------//
15091 case CMBTRIGWPNLEVEL:
15092 {
15093 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15094 {
15095 trig->triggerlevel = vbound(value/10000, 0, 214748);
15096 }
15097 break;
15098 }
15099 case CMBTRIGREQITEM:
15100 {
15101 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15102 {
15103 trig->triggeritem = vbound(value/10000, 0, MAXITEMS-1);
15104 }
15105 break;
15106 }
15107 case CMBTRIGTIMER:
15108 {
15109 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15110 {
15111 trig->trigtimer = vbound(value/10000, 0, 65535);
15112 }
15113 break;
15114 }
15115 case CMBTRIGSFX:
15116 {
15117 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15118 {
15119 trig->trigsfx = vbound(value/10000, 0, 255);
15120 }
15121 break;
15122 }
15123 case CMBTRIGCHANGECMB:
15124 {
15125 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15126 {
15127 trig->trigchange = value/10000;
15128 }
15129 break;
15130 }
15131 case CMBTRIGCSETCHANGE:
15132 {
15133 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15134 {
15135 trig->trigcschange = vbound(value/10000, -128, 127);
15136 }
15137 break;
15138 }
15139 case CMBTRIGPROX:
15140 {
15141 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15142 {
15143 trig->trigprox = vbound(value/10000, 0, 65535);
15144 }
15145 break;
15146 }
15147 case CMBTRIGLIGHTBEAM:
15148 {
15149 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15150 {
15151 trig->triglbeam = vbound(value/10000,0,32);
15152 }
15153 break;
15154 }
15155 case CMBTRIGCTR:
15156 {
15157 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15158 {
15159 trig->trigctr = vbound(value/10000, sscMIN, MAX_COUNTERS-1);
15160 }
15161 break;
15162 }
15163 case CMBTRIGCTRAMNT:
15164 {
15165 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15166 {
15167 trig->trigctramnt = vbound(value/10000, -65535, 65535);
15168 }
15169 break;
15170 }
15171 case CMBTRIGCOOLDOWN:
15172 {
15173 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15174 {
15175 trig->trigcooldown = vbound(value/10000, 0, 255);
15176 }
15177 break;
15178 }
15179 case CMBTRIGCOPYCAT:
15180 {
15181 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15182 {
15183 trig->trigcopycat = vbound(value/10000, 0, 255);
15184 }
15185 break;
15186 }
15187 case CMBTRIGITEMPICKUP:
15188 {
15189 const int32_t allowed_pflags = ipHOLDUP | ipTIMER | ipSECRETS | ipCANGRAB;
15190 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15191 {
15192 trig->spawnip = (value/10000)&allowed_pflags;
15193 }
15194 break;
15195 }
15196 case CMBTRIGEXSTATE:
15197 {
15198 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15199 {
15200 trig->exstate = vbound(value/10000, -1, 31);
15201 }
15202 break;
15203 }
15204 case CMBTRIGEXDOORDIR:
15205 {
15206 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15207 {
15208 trig->exdoor_dir = vbound(value/10000, -1, 3);
15209 }
15210 break;
15211 }
15212 case CMBTRIGEXDOORIND:
15213 {
15214 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15215 {
15216 trig->exdoor_ind = vbound(value/10000, 0, 7);
15217 }
15218 break;
15219 }
15220 case CMBTRIGSPAWNENEMY:
15221 {
15222 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15223 {
15224 trig->spawnenemy = vbound(value/10000, 0, 511);
15225 }
15226 break;
15227 }
15228 case CMBTRIGSPAWNITEM:
15229 {
15230 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15231 {
15232 trig->spawnitem = vbound(value/10000, -255, 255);
15233 }
15234 break;
15235 }
15236 case CMBTRIGLSTATE:
15237 {
15238 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15239 {
15240 trig->trig_lstate = vbound(value/10000, 0, 31);
15241 }
15242 break;
15243 }
15244 case CMBTRIGGSTATE:
15245 {
15246 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15247 {
15248 trig->trig_gstate = vbound(value/10000, 0, 255);
15249 }
15250 break;
15251 }
15252 case CMBTRIGGTIMER:
15253 {
15254 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15255 {
15256 trig->trig_statetime = vbound(value/10000, 0, 214748);
15257 }
15258 break;
15259 }
15260 case CMBTRIGGENSCRIPT:
15261 {
15262 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15263 {
15264 trig->trig_genscr = vbound(value/10000, 0, 65535);
15265 }
15266 break;
15267 }
15268 case CMBTRIGGROUP:
15269 {
15270 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15271 {
15272 trig->trig_group = vbound(value/10000, 0, 255);
15273 }
15274 break;
15275 }
15276 case CMBTRIGGROUPVAL:
15277 {
15278 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15279 {
15280 trig->trig_group_val = vbound(value/10000, 0, 65535);
15281 }
15282 break;
15283 }
15284 case CMBTRIGLITEMS:
15285 {
15286 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15287 {
15288 trig->trig_levelitems = (value/10000) & LI_ALL;
15289 }
15290 break;
15291 }
15292 case CMBTRIGDMAPLVL:
15293 {
15294 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15295 {
15296 trig->trigdmlevel = vbound(value/10000, -1, MAXLEVELS-1);
15297 }
15298 break;
15299 }
15300 case CMBTRIGTINTR:
15301 {
15302 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15303 {
15304 trig->trigtint[0] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
15305 }
15306 break;
15307 }
15308 case CMBTRIGTINTG:
15309 {
15310 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15311 {
15312 trig->trigtint[1] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
15313 }
15314 break;
15315 }
15316 case CMBTRIGTINTB:
15317 {
15318 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15319 {
15320 trig->trigtint[2] = scripting_write_pal_color(vbound(value/10000, -scripting_max_color_val, scripting_max_color_val));
15321 }
15322 break;
15323 }
15324 case CMBTRIGLVLPAL:
15325 {
15326 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15327 {
15328 trig->triglvlpalette = vbound(value/10000, -1, 512);
15329 }
15330 break;
15331 }
15332 case CMBTRIGBOSSPAL:
15333 {
15334 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15335 {
15336 trig->trigbosspalette = vbound(value/10000, -1, 29);
15337 }
15338 break;
15339 }
15340 case CMBTRIGQUAKETIME:
15341 {
15342 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15343 {
15344 trig->trigquaketime = zc_max(value/10000, -1);
15345 }
15346 break;
15347 }
15348 case CMBTRIGWAVYTIME:
15349 {
15350 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15351 {
15352 trig->trigwavytime = zc_max(value/10000, -1);
15353 }
15354 break;
15355 }
15356 case CMBTRIGSWORDJINX:
15357 {
15358 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15359 {
15360 trig->trig_swjinxtime = zc_max(value/10000, -2);
15361 }
15362 break;
15363 }
15364 case CMBTRIGITEMJINX:
15365 {
15366 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15367 {
15368 trig->trig_itmjinxtime = zc_max(value/10000, -2);
15369 }
15370 break;
15371 }
15372 case CMBTRIGSHIELDJINX:
15373 {
15374 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15375 {
15376 trig->trig_shieldjinxtime = zc_max(value/10000, -2);
15377 }
15378 break;
15379 }
15380 case CMBTRIGSTUN:
15381 {
15382 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15383 {
15384 trig->trig_stuntime = zc_max(value/10000, -2);
15385 }
15386 break;
15387 }
15388 case CMBTRIGBUNNY:
15389 {
15390 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15391 {
15392 trig->trig_bunnytime = zc_max(value/10000, -2);
15393 }
15394 break;
15395 }
15396 case CMBTRIGPUSHTIME:
15397 {
15398 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15399 {
15400 trig->trig_pushtime = vbound(value/10000, 0, 255);
15401 }
15402 break;
15403 }
15404 case CMBTRIGGERPROMPTCID:
15405 {
15406 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15407 trig->prompt_cid = vbound(value/10000, 0, MAXCOMBOS-1);
15408 break;
15409 }
15410 case CMBTRIGGERPROMPTCS:
15411 {
15412 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15413 trig->prompt_cs = (value/10000)&15;
15414 break;
15415 }
15416 case CMBTRIGGERFAILPROMPTCID:
15417 {
15418 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15419 trig->fail_prompt_cid = vbound(value/10000, 0, MAXCOMBOS-1);
15420 break;
15421 }
15422 case CMBTRIGGERFAILPROMPTCS:
15423 {
15424 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15425 trig->fail_prompt_cs = (value/10000)&15;
15426 break;
15427 }
15428 case CMBTRIGGERPROMPTX:
15429 {
15430 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15431 trig->prompt_x = vbound(value/10000, -32768, 32767);
15432 break;
15433 }
15434 case CMBTRIGGERPROMPTY:
15435 {
15436 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15437 trig->prompt_y = vbound(value/10000, -32768, 32767);
15438 break;
15439 }
15440 case CMBTRIGGERTRIGSTR:
15441 {
15442 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15443 trig->trig_msgstr = vbound(value/10000, 0, msg_count-1);
15444 break;
15445 }
15446 case CMBTRIGGERFAILSTR:
15447 {
15448 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15449 trig->fail_msgstr = vbound(value/10000, 0, msg_count-1);
15450 break;
15451 }
15452 case CMBTRIGGERPLAYERBOUNCE:
15453 {
15454 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15455 trig->player_bounce = zslongToFix(value);
15456 break;
15457 }
15458 case CMBTRIGGERREQPLAYERZ:
15459 {
15460 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15461 trig->req_player_z = zslongToFix(value);
15462 break;
15463 }
15464 case CMBTRIGGERDESTHEROX:
15465 {
15466 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15467 trig->dest_player_x = zslongToFix(value);
15468 break;
15469 }
15470 case CMBTRIGGERDESTHEROY:
15471 {
15472 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15473 trig->dest_player_y = zslongToFix(value);
15474 break;
15475 }
15476 case CMBTRIGGERDESTHEROZ:
15477 {
15478 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15479 trig->dest_player_z = zslongToFix(value);
15480 break;
15481 }
15482 case CMBTRIGGERREQPLAYERJUMP:
15483 {
15484 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15485 trig->req_player_jump = zslongToFix(value);
15486 break;
15487 }
15488 case CMBTRIGGERREQPLAYERX:
15489 {
15490 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15491 trig->req_player_x = zslongToFix(value);
15492 break;
15493 }
15494 case CMBTRIGGERREQPLAYERY:
15495 {
15496 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15497 trig->req_player_y = zslongToFix(value);
15498 break;
15499 }
15500 case CMBTRIGGERFORCEPLAYERDIR:
15501 {
15502 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15503 trig->dest_player_dir = vbound(value/10000, 3, -1);
15504 break;
15505 }
15506 case CMBTRIGGERICECOMBO:
15507 {
15508 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15509 trig->force_ice_combo = vbound(value/10000, MAXCOMBOS-1, -1);
15510 break;
15511 }
15512 case CMBTRIGGERICEVX:
15513 {
15514 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15515 trig->force_ice_vx = zslongToFix(value);
15516 break;
15517 }
15518 case CMBTRIGGERICEVY:
15519 {
15520 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15521 trig->force_ice_vy = zslongToFix(value);
15522 break;
15523 }
15524 case CMBTRIGGER_GRAVITY:
15525 {
15526 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15527 trig->trig_gravity = zslongToFix(value);
15528 break;
15529 }
15530 case CMBTRIGGER_TERMINAL_VELOCITY:
15531 {
15532 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
15533 trig->trig_terminal_v = zslongToFix(value);
15534 break;
15535 }
15536 ///----------------------------------------------------------------------------------------------------//
15537 //npcdata nd-> Variables
15538
15539 #define SET_NPCDATA_VAR_INT(member, str) \
15540 { \
15541 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15542 nd->member = vbound((value / 10000),0,214747); \
15543 } \
15544
15545 #define SET_NPCDATA_VAR_DWORD(member, str) \
15546 { \
15547 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15548 nd->member = vbound((value / 10000),0,32767); \
15549 } \
15550
15551 #define SET_NPCDATA_VAR_ENUM(member, str) \
15552 { \
15553 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15554 nd->member = (decltype(guysbuf[GET_REF(npcdataref)].member))vbound((value / 10000),0,32767); \
15555 } \
15556
15557 #define SET_NPCDATA_VAR_BYTE(member, str) \
15558 { \
15559 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15560 nd->member = vbound((value / 10000),0,255); \
15561 } \
15562
15563 #define SET_NPCDATA_FLAG(member, str) \
15564 { \
15565 int32_t flag = (value/10000); \
15566 if( auto nd = checkNPCData(GET_REF(npcdataref)) ) \
15567 { \
15568 if ( flag ) \
15569 { \
15570 nd->member|=flag; \
15571 } \
15572 else nd->member|= ~flag; \
15573 } \
15574 } \
15575
15576 case NPCDATATILE: SET_NPCDATA_VAR_BYTE(tile, "Tile"); break;
15577 case NPCDATAWIDTH: SET_NPCDATA_VAR_BYTE(width, "Width"); break;
15578 case NPCDATAHEIGHT: SET_NPCDATA_VAR_BYTE(height, "Height"); break;
15579 case NPCDATAFLAGS1: SET_NPCDATA_VAR_ENUM(flags, "Flags (deprecated)"); break;
15580 case NPCDATAFLAGS2: SET_NPCDATA_VAR_ENUM(flags, "Flags2 (deprecated)"); break;
15581 case NPCDATASTILE: SET_NPCDATA_VAR_BYTE(s_tile, "STile"); break;
15582 case NPCDATASWIDTH: SET_NPCDATA_VAR_BYTE(s_width, "SWidth"); break;
15583 case NPCDATASHEIGHT: SET_NPCDATA_VAR_BYTE(s_height, "SHeight"); break;
15584 case NPCDATAETILE: SET_NPCDATA_VAR_INT(e_tile, "ExTile"); break;
15585 case NPCDATAEWIDTH: SET_NPCDATA_VAR_BYTE(e_width, "ExWidth"); break;
15586 case NPCDATASCRIPT: SET_NPCDATA_VAR_BYTE(script, "Script"); break;
15587 case NPCDATAEHEIGHT: SET_NPCDATA_VAR_BYTE(e_height, "ExHeight"); break;
15588 case NPCDATAHP: SET_NPCDATA_VAR_DWORD(hp, "HP"); break;
15589 case NPCDATATYPE: SET_NPCDATA_VAR_DWORD(type, "Family"); break;
15590 case NPCDATACSET: SET_NPCDATA_VAR_DWORD(cset, "CSet"); break;
15591 case NPCDATAANIM: SET_NPCDATA_VAR_DWORD(anim, "Anim"); break;
15592 case NPCDATAEANIM: SET_NPCDATA_VAR_DWORD(e_anim, "ExAnim"); break;
15593 case NPCDATAFRAMERATE: SET_NPCDATA_VAR_DWORD(frate, "Framerate"); break;
15594 case NPCDATAEFRAMERATE: SET_NPCDATA_VAR_DWORD(e_frate, "ExFramerate"); break;
15595 case NPCDATATOUCHDAMAGE: SET_NPCDATA_VAR_DWORD(dp, "TouchDamage"); break;
15596 case NPCDATAWEAPONDAMAGE: SET_NPCDATA_VAR_DWORD(wdp, "WeaponDamage"); break;
15597 case NPCDATAWEAPON: SET_NPCDATA_VAR_DWORD(weapon, "Weapon"); break;
15598 case NPCDATARANDOM: SET_NPCDATA_VAR_DWORD(rate, "Random"); break;
15599 case NPCDATAHALT: SET_NPCDATA_VAR_DWORD(hrate, "Haltrate"); break;
15600 case NPCDATASTEP: SET_NPCDATA_VAR_DWORD(step, "Step"); break;
15601 case NPCDATAHOMING: SET_NPCDATA_VAR_DWORD(homing, "Homing"); break;
15602 case NPCDATAHUNGER: SET_NPCDATA_VAR_DWORD(grumble, "Hunger"); break;
15603 case NPCDATADROPSET: SET_NPCDATA_VAR_DWORD(item_set, "Dropset"); break;
15604 case NPCDATABGSFX: SET_NPCDATA_VAR_DWORD(bgsfx, "BGSFX"); break;
15605 case NPCDATADEATHSFX: SET_NPCDATA_VAR_BYTE(deadsfx, "DeathSFX"); break;
15606 case NPCDATAHITSFX: SET_NPCDATA_VAR_BYTE(hitsfx, "HitSFX"); break;
15607 case NPCDATAXOFS: SET_NPCDATA_VAR_INT(xofs, "DrawXOffset"); break;
15608 case NPCDATAYOFS: SET_NPCDATA_VAR_INT(yofs, "DrawYOffset"); break;
15609 case NPCDATAZOFS: SET_NPCDATA_VAR_INT(zofs, "DrawZOffset"); break;
15610 case NPCDATAHXOFS: SET_NPCDATA_VAR_INT(hxofs, "HitXOffset"); break;
15611 case NPCDATAHYOFS: SET_NPCDATA_VAR_INT(hyofs, "HitYOffset"); break;
15612 case NPCDATAHITWIDTH: SET_NPCDATA_VAR_INT(hxsz, "HitWidth"); break;
15613 case NPCDATAHITHEIGHT: SET_NPCDATA_VAR_INT(hysz, "HitHeight"); break;
15614 case NPCDATAHITZ: SET_NPCDATA_VAR_INT(hzsz, "HitZHeight"); break;
15615 case NPCDATATILEWIDTH: SET_NPCDATA_VAR_INT(txsz, "TileWidth"); break;
15616 case NPCDATATILEHEIGHT: SET_NPCDATA_VAR_INT(tysz, "TileHeight"); break;
15617 case NPCDATAWPNSPRITE: SET_NPCDATA_VAR_INT(wpnsprite, "WeaponSprite"); break;
15618 case NPCDATAWEAPONSCRIPT:
15619 {
15620 if(checkNPCDataRef())
15621 guysbuf[GET_REF(npcdataref)].weap_data.script = vbound((value / 10000),0,214747);
15622 break;
15623 }
15624 case NPCDATASIZEFLAG: SET_NPCDATA_VAR_INT(SIZEflags, "SizeFlags"); break;
15625
15626 case NPCDATAFROZENTILE: SET_NPCDATA_VAR_INT(frozentile, "FrozenTile"); break;
15627 case NPCDATAFROZENCSET: SET_NPCDATA_VAR_INT(frozencset, "FrozenCSet"); break;
15628 case NPCDATAFIRESFX: SET_NPCDATA_VAR_BYTE(firesfx, "WeaponSFX"); break;
15629
15630 case NPCDSHADOWSPR:
15631 {
15632 if (checkNPCDataRef())
15633 guysbuf[GET_REF(npcdataref)].spr_shadow = vbound(value/10000, 0, 255);
15634 break;
15635 }
15636 case NPCDSPAWNSPR:
15637 {
15638 if (checkNPCDataRef())
15639 guysbuf[GET_REF(npcdataref)].spr_spawn = vbound(value/10000, 0, 255);
15640 break;
15641 }
15642 case NPCDDEATHSPR:
15643 {
15644 if (checkNPCDataRef())
15645 guysbuf[GET_REF(npcdataref)].spr_death = vbound(value/10000, 0, 255);
15646 break;
15647 }
15648
15649
15650 ///----------------------------------------------------------------------------------------------------//
15651 //Dropset Variables
15652
15653 case DROPSETNULLCHANCE:
15654 {
15655 if(ri->dropsetdataref > MAXITEMDROPSETS)
15656 {
15657 Z_scripterrlog("Invalid dropset pointer %d\n", ri->dropsetdataref);
15658 break;
15659 }
15660 item_drop_sets[GET_REF(dropsetdataref)].chance[0] = vbound((value / 10000),0,32767);
15661 break;
15662 }
15663
15664 ///----------------------------------------------------------------------------------------------------//
15665 //Audio Variables
15666
15667 case AUDIOPAN:
15668 {
15669 if ( !(FFCore.coreflags&FFCORE_SCRIPTED_PANSTYLE) )
15670 {
15671 FFCore.usr_panstyle = FFScript::do_getSFX_pan();
15672 FFCore.SetFFEngineFlag(FFCORE_SCRIPTED_PANSTYLE,true);
15673 }
15674 FFScript::do_setSFX_pan(value/10000);
15675 break;
15676 }
15677
15678 ///----------------------------------------------------------------------------------------------------//
15679 //Graphics->
15680
15681 case NUMDRAWS:
15682 break;
15683
15684 case MAXDRAWS: break;
15685
15686 ///----------------------------------------------------------------------------------------------------//
15687 //Misc./Internal
15688 case SP:
15689 ri->sp = value / 10000;
15690 break;
15691
15692 case SP2:
15693 ri->sp = value;
15694 break;
15695
15696 case PC:
15697 ri->pc = value;
15698 break;
15699
15700 case SWITCHKEY:
15701 ri->switchkey = value;
15702 break;
15703
15704 case SCRIPTRAM:
15705 case GLOBALRAM:
15706 531793831 ArrayH::setElement(GET_D(rINDEX), GET_D(rINDEX2) / 10000, value);
15707 531793831 break;
15708
15709 case SCRIPTRAMD:
15710 case GLOBALRAMD:
15711 ArrayH::setElement(GET_D(rINDEX), 0, value);
15712 break;
15713
15714 case REFFFC:
15715
2/2
✓ Branch 0 taken 6428643 times.
✓ Branch 1 taken 639949480 times.
646378123 ri->ffcref = ZScriptVersion::ffcRefIsSpriteId() ? value : value / 10000;
15716 646378123 break;
15717
15718 case REFITEM:
15719 2240371 ri->itemref = value;
15720 2240371 break;
15721
15722 case REFITEMDATA:
15723 59236618 ri->itemdataref = value;
15724 59236618 break;
15725
15726 case REFLWPN:
15727 12785291 ri->lwpnref = value;
15728 12785291 break;
15729
15730 case REFEWPN:
15731 48396677 ri->ewpnref = value;
15732 48396677 break;
15733
15734 case REFNPC:
15735 169200048 ri->npcref = value;
15736 169200048 break;
15737
15738 case REFSPRITE:
15739 109290671 ri->spriteref = value;
15740 109290671 break;
15741
15742 132051524 case REFMAPDATA: ri->mapdataref = value; break;
15743 case REFSCREEN: ri->screenref = value; break;
15744 12299117 case REFCOMBODATA: ri->combodataref = value; break;
15745 case REFCOMBOTRIGGER: ri->combotriggerref = value; break;
15746 22412 case REFSPRITEDATA: ri->spritedataref = value; break;
15747 412757 case REFBITMAP: ri->bitmapref = value; break;
15748 2 case REFNPCDATA: ri->npcdataref = value; break;
15749
15750 979359 case REFDMAPDATA: ri->dmapdataref = value; break;
15751 case REFSHOPDATA: ri->shopdataref = value; break;
15752 220 case REFMSGDATA: ri->msgdataref = value; break;
15753
15754
15755 10 case REFDROPSETDATA: ri->dropsetdataref = value; break;
15756 case REFBOTTLETYPE: ri->bottletyperef = value; break;
15757 case REFBOTTLESHOP: ri->bottleshopref = value; break;
15758 10426928 case REFGENERICDATA: ri->genericdataref = value; break;
15759 284 case REFFILE: ri->fileref = value; break;
15760 case REFDIRECTORY: ri->directoryref = value; break;
15761 case REFSTACK: ri->stackref = value; break;
15762 109743 case REFSUBSCREENDATA: ri->subscreendataref = value; break;
15763 20806 case REFSUBSCREENPAGE: ri->subscreenpageref = value; break;
15764 103742 case REFSUBSCREENWIDG: ri->subscreenwidgref = value; break;
15765 521996 case REFRNG: ri->rngref = value; break;
15766 case REFWEBSOCKET: ri->websocketref = value; break;
15767 192996 case CLASS_THISKEY: ri->thiskey = value; break;
15768 1134 case CLASS_THISKEY2: ri->thiskey2 = value; break;
15769 7263 case REFPALDATA: ri->paldataref = value; break;
15770
15771 //-------------------------------------------------------------------------------------------------
15772
15773 case GENDATARUNNING:
15774 {
15775
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 137 times.
137 if(user_genscript* scr = checkGenericScr(GET_REF(genericdataref)))
15776 {
15777
1/2
✓ Branch 0 taken 137 times.
✗ Branch 1 not taken.
137 if(value)
15778 137 scr->launch();
15779 else scr->quit();
15780 137 }
15781 137 break;
15782 }
15783 case GENDATASIZE:
15784 {
15785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
67 if(user_genscript* scr = checkGenericScr(GET_REF(genericdataref)))
15786 {
15787 67 scr->dataResize(value/10000);
15788 67 }
15789 67 break;
15790 }
15791
15792 //----------------------------------------------------------------------------------------------------//
15793
15794 case PORTALX:
15795 {
15796 if(portal* p = checkPortal(GET_REF(portalref)))
15797 p->x = zslongToFix(value);
15798 break;
15799 }
15800 case PORTALY:
15801 {
15802 if(portal* p = checkPortal(GET_REF(portalref)))
15803 p->y = zslongToFix(value);
15804 break;
15805 }
15806 case PORTALDMAP:
15807 {
15808 if(portal* p = checkPortal(GET_REF(portalref)))
15809 p->destdmap = vbound(value/10000,-1,MAXDMAPS-1);
15810 break;
15811 }
15812 case PORTALSCREEN:
15813 {
15814 if(portal* p = checkPortal(GET_REF(portalref)))
15815 p->destscr = vbound(value/10000,0,255);
15816 break;
15817 }
15818 case PORTALACLK:
15819 {
15820 if(portal* p = checkPortal(GET_REF(portalref)))
15821 p->aclk = vbound(value/10000, 0, 9999);
15822 break;
15823 }
15824 case PORTALAFRM:
15825 {
15826 if(portal* p = checkPortal(GET_REF(portalref)))
15827 p->aframe = vbound(value/10000, 0, 9999);
15828 break;
15829 }
15830 case PORTALOTILE:
15831 {
15832 if(portal* p = checkPortal(GET_REF(portalref)))
15833 p->o_tile = vbound(value/10000, 0, NEWMAXTILES-1);
15834 break;
15835 }
15836 case PORTALASPD:
15837 {
15838 if(portal* p = checkPortal(GET_REF(portalref)))
15839 p->aspd = vbound(value/10000, 0, 9999);
15840 break;
15841 }
15842 case PORTALFRAMES:
15843 {
15844 if(portal* p = checkPortal(GET_REF(portalref)))
15845 p->frames = vbound(value/10000, 0, 9999);
15846 break;
15847 }
15848 case PORTALSAVED:
15849 {
15850 if(ri->portalref < 0 || value < 0) break;
15851 if(portal* p = checkPortal(GET_REF(portalref)))
15852 {
15853 if(!value)
15854 p->saved_data = 0;
15855 else if(savedportal* sp = checkSavedPortal(value))
15856 p->saved_data = sp->getUID();
15857 }
15858 break;
15859 }
15860 case PORTALCLOSEDIS:
15861 {
15862 if(portal* p = checkPortal(GET_REF(portalref)))
15863 p->prox_active = value==0; //Inverted
15864 break;
15865 }
15866 case REFPORTAL:
15867 {
15868 ri->portalref = value;
15869 break;
15870 }
15871 case REFSAVPORTAL:
15872 {
15873 ri->savportalref = value;
15874 break;
15875 }
15876 case PORTALWARPSFX:
15877 {
15878 if(portal* p = checkPortal(GET_REF(portalref)))
15879 p->wsfx = vbound(value/10000,0,255);
15880 break;
15881 }
15882 case PORTALWARPVFX:
15883 {
15884 if(portal* p = checkPortal(GET_REF(portalref)))
15885 p->weffect = vbound(value/10000,0,255);
15886 break;
15887 }
15888 case SAVEDPORTALX:
15889 {
15890 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15891 p->x = value;
15892 break;
15893 }
15894 case SAVEDPORTALY:
15895 {
15896 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15897 p->y = value;
15898 break;
15899 }
15900 case SAVEDPORTALSRCDMAP:
15901 {
15902 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15903 p->srcdmap = vbound(value/10000, -1, MAXDMAPS-1);
15904 break;
15905 }
15906 case SAVEDPORTALDESTDMAP:
15907 {
15908 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15909 p->destdmap = vbound(value/10000, -1, MAXDMAPS-1);
15910 break;
15911 }
15912 case SAVEDPORTALSRCSCREEN:
15913 {
15914 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15915 p->srcscr = vbound(value/10000,0,255);
15916 break;
15917 }
15918 case SAVEDPORTALDSTSCREEN:
15919 {
15920 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15921 p->destscr = vbound(value/10000,0,255);
15922 break;
15923 }
15924 case SAVEDPORTALWARPSFX:
15925 {
15926 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15927 p->sfx = vbound(value/10000,0,255);
15928 break;
15929 }
15930 case SAVEDPORTALWARPVFX:
15931 {
15932 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15933 p->warpfx = vbound(value/10000,0,255);
15934 break;
15935 }
15936 case SAVEDPORTALSPRITE:
15937 {
15938 if(savedportal* p = checkSavedPortal(GET_REF(savportalref)))
15939 p->spr = vbound(value/10000,0,255);
15940 break;
15941 }
15942 case SAVEDPORTALPORTAL:
15943 {
15944 if(ri->savportalref < 0 || value < 0) break;
15945 if(savedportal* sp = checkSavedPortal(GET_REF(savportalref)))
15946 {
15947 int32_t id = getPortalFromSaved(sp);
15948 if(id == value) break; //no change
15949 portal* p = checkPortal(value);
15950 if(p)
15951 {
15952 p->saved_data = sp->getUID();
15953 if(id > 0)
15954 {
15955 portal* p = checkPortal(id);
15956 p->saved_data = 0;
15957 }
15958 }
15959 }
15960 break;
15961 }
15962
15963 case GAMENUMASUB:
15964 {
15965 if(value >= 0)
15966 {
15967 size_t sz = vbound(value/10000, 0, 256);
15968 while(subscreens_active.size() < sz)
15969 {
15970 auto& sub = subscreens_active.emplace_back();
15971 sub.sub_type = sstACTIVE;
15972 }
15973 while(subscreens_active.size() > sz)
15974 subscreens_active.pop_back();
15975 }
15976 break;
15977 }
15978 case GAMENUMPSUB:
15979 {
15980 if(value >= 0)
15981 {
15982 size_t sz = vbound(value/10000, 0, 256);
15983 while(subscreens_passive.size() < sz)
15984 {
15985 auto& sub = subscreens_passive.emplace_back();
15986 sub.sub_type = sstPASSIVE;
15987 }
15988 while(subscreens_passive.size() > sz)
15989 subscreens_passive.pop_back();
15990 }
15991 break;
15992 }
15993 case GAMENUMOSUB:
15994 {
15995 if(value >= 0)
15996 {
15997 size_t sz = vbound(value/10000, 0, 256);
15998 while(subscreens_overlay.size() < sz)
15999 {
16000 auto& sub = subscreens_overlay.emplace_back();
16001 sub.sub_type = sstOVERLAY;
16002 }
16003 while(subscreens_overlay.size() > sz)
16004 subscreens_overlay.pop_back();
16005 }
16006 break;
16007 }
16008 case GAMENUMMSUB:
16009 {
16010 if(value >= 0)
16011 {
16012 size_t sz = vbound(value/10000, 0, 256);
16013 while(subscreens_map.size() < sz)
16014 {
16015 auto& sub = subscreens_map.emplace_back();
16016 sub.sub_type = sstMAP;
16017 }
16018 while(subscreens_map.size() > sz)
16019 subscreens_map.pop_back();
16020 }
16021 break;
16022 }
16023 ///----------------------------------------------------------------------------------------------------//
16024
16025 case SUBDATACURPG:
16026 {
16027
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
16028
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if(sub->sub_type == sstACTIVE || sub->sub_type == sstMAP)
16029 3 sub->curpage = vbound(value/10000,0,sub->pages.size()-1);
16030 3 break;
16031 }
16032 case SUBDATANUMPG:
16033 {
16034 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
16035 if((sub->sub_type == sstACTIVE || sub->sub_type == sstMAP) && value >= 10000)
16036 {
16037 size_t sz = value/10000;
16038 while(sub->pages.size() < sz)
16039 if(!sub->add_page(MAX_SUBSCR_PAGES))
16040 break;
16041 while(sub->pages.size() > sz)
16042 sub->delete_page(sub->pages.size()-1);
16043 }
16044 break;
16045 }
16046 case SUBDATATYPE: break; //READONLY
16047 ///---- ACTIVE SUBSCREENS ONLY
16048 case SUBDATACURSORPOS:
16049 {
16050 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16051 {
16052 SubscrPage& pg = sub->cur_page();
16053 //Should this be sanity checked? Or should nulling out
16054 // the cursor by setting it invalid be allowed? -Em
16055 pg.cursor_pos = vbound(value/10000,0,255);
16056 }
16057 break;
16058 }
16059 case SUBDATASCRIPT:
16060 {
16061 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16062 sub->script = vbound(value/10000,0,NUMSCRIPTSSUBSCREEN-1);
16063 break;
16064 }
16065
16066 case SUBDATATRANSLEFTTY:
16067 {
16068 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16069 {
16070 auto& trans = sub->trans_left;
16071 trans.type = vbound(value/10000,0,sstrMAX-1);
16072 }
16073 break;
16074 }
16075 case SUBDATATRANSLEFTSFX:
16076 {
16077 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16078 {
16079 auto& trans = sub->trans_left;
16080 trans.tr_sfx = vbound(value/10000,0,255);
16081 }
16082 break;
16083 }
16084 case SUBDATATRANSRIGHTTY:
16085 {
16086 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16087 {
16088 auto& trans = sub->trans_right;
16089 trans.type = vbound(value/10000,0,sstrMAX-1);
16090 }
16091 break;
16092 }
16093 case SUBDATATRANSRIGHTSFX:
16094 {
16095 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16096 {
16097 auto& trans = sub->trans_right;
16098 trans.tr_sfx = vbound(value/10000,0,255);
16099 }
16100 break;
16101 }
16102 case SUBDATASELECTORDSTX:
16103 {
16104 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16105 sub->selector_setting.x = vbound(value/10000,-32768,32767);
16106 break;
16107 }
16108 case SUBDATASELECTORDSTY:
16109 {
16110 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16111 sub->selector_setting.y = vbound(value/10000,-32768,32767);
16112 break;
16113 }
16114 case SUBDATASELECTORDSTW:
16115 {
16116 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16117 sub->selector_setting.w = vbound(value/10000,-32768,32767);
16118 break;
16119 }
16120 case SUBDATASELECTORDSTH:
16121 {
16122 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16123 sub->selector_setting.h = vbound(value/10000,-32768,32767);
16124 break;
16125 }
16126 ///---- CURRENTLY OPEN ACTIVE SUBSCREEN ONLY
16127 case SUBDATATRANSCLK:
16128 {
16129
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16130 {
16131
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(sub != CURRENT_ACTIVE_SUBSCREEN)
16132 Z_scripterrlog("'subscreendata->TransClock' is only"
16133 " valid for the current active/map subscreen!\n");
16134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(subscreen_open)
16135 {
16136 11 int val = value/10000;
16137
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(val < 0)
16138 subscrpg_clear_animation();
16139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(!subscr_pg_animating)
16140 {
16141 11 SubscrTransition tr = subscr_pg_transition;
16142 11 tr.tr_sfx = 0;
16143
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 subscrpg_animate(subscr_pg_from,subscr_pg_to,tr,*CURRENT_ACTIVE_SUBSCREEN,*CURRENT_ACTIVE_SUBSCREEN);
16144 11 subscr_pg_clk = val;
16145 11 }
16146 else subscr_pg_clk = val;
16147 11 }
16148 11 }
16149 11 break;
16150 }
16151 case SUBDATATRANSTY:
16152 {
16153
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16154 {
16155 11 auto& trans = subscr_pg_transition;
16156
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(sub != CURRENT_ACTIVE_SUBSCREEN)
16157 Z_scripterrlog("'subscreendata->TransType' is only"
16158 " valid for the current active/map subscreen!\n");
16159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(subscreen_open)
16160 11 trans.type = vbound(value/10000,0,sstrMAX-1);
16161 11 }
16162 11 break;
16163 }
16164 case SUBDATATRANSFROMPG:
16165 {
16166
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16167 {
16168
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 if(sub != CURRENT_ACTIVE_SUBSCREEN)
16169 Z_scripterrlog("'subscreendata->TransFromPage' is only"
16170 " valid for the current active/map subscreen!\n");
16171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(subscreen_open)
16172 11 subscr_pg_from = vbound(value/10000,0,sub->pages.size()-1);
16173 11 }
16174 11 break;
16175 }
16176 case SUBDATATRANSTOPG:
16177 {
16178
3/6
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
11 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref), {sstACTIVE, sstMAP}))
16179 {
16180
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 if(sub != CURRENT_ACTIVE_SUBSCREEN)
16181 Z_scripterrlog("'subscreendata->TransToPage' is only"
16182 " valid for the current active/map subscreen!\n");
16183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 else if(subscreen_open)
16184 11 subscr_pg_to = vbound(value/10000,0,sub->pages.size()-1);
16185 11 }
16186 11 break;
16187 }
16188
16189 ///----------------------------------------------------------------------------------------------------//
16190 case SUBPGINDEX: break; //READ-ONLY
16191 case SUBPGNUMWIDG: break; //READ-ONLY
16192 case SUBPGSUBDATA: break; //READ-ONLY
16193 case SUBPGCURSORPOS:
16194 {
16195 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
16196 pg->cursor_pos = vbound(value/10000,0,255);
16197 break;
16198 }
16199 ///----------------------------------------------------------------------------------------------------//
16200 ///---- ANY WIDGET TYPE
16201 case SUBWIDGTYPE: break; //READ-ONLY
16202 case SUBWIDGINDEX: break; //READ-ONLY
16203 case SUBWIDGPAGE: break; //READ-ONLY
16204 case SUBWIDGDISPITM: break; //READ-ONLY
16205 case SUBWIDGEQPITM: break; //READ-ONLY
16206 case SUBWIDGPOS:
16207 {
16208 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16209 widg->pos = vbound(value/10000,0,255);
16210 break;
16211 }
16212 case SUBWIDGX:
16213 {
16214
2/4
✓ Branch 0 taken 132 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 132 times.
132 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16215 132 widg->x = vbound(value/10000,-32768,32767);
16216 132 break;
16217 }
16218 case SUBWIDGY:
16219 {
16220
2/4
✓ Branch 0 taken 4247 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4247 times.
4247 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16221 4247 widg->y = vbound(value/10000,-32768,32767);
16222 4247 break;
16223 }
16224 case SUBWIDGW:
16225 {
16226 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16227 widg->w = vbound(value/10000,0,65535);
16228 break;
16229 }
16230 case SUBWIDGH:
16231 {
16232 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16233 widg->h = vbound(value/10000,0,65535);
16234 break;
16235 }
16236 case SUBWIDGREQCOUNTER:
16237 {
16238 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16239 widg->req_counter = vbound(value/10000,sscMIN,MAX_COUNTERS);
16240 break;
16241 }
16242 case SUBWIDGREQCOUNTERCOND:
16243 {
16244 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16245 widg->req_counter_cond_type = vbound(value/10000,CONDTY_NONE,CONDTY_MAX-1);
16246 break;
16247 }
16248 case SUBWIDGREQCOUNTERVAL:
16249 {
16250 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16251 widg->req_counter_val = vbound(value/10000,0,65535);
16252 break;
16253 }
16254 case SUBWIDGREQLITEMS:
16255 {
16256 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16257 widg->req_litems = vbound(value/10000,0,LI_ALL);
16258 break;
16259 }
16260 case SUBWIDGREQLITEMLEVEL:
16261 {
16262 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16263 widg->req_litem_level = vbound(value/10000,-1,MAXLEVELS);
16264 break;
16265 }
16266 case SUBWIDGREQ_LEVEL_STATE_LEVEL:
16267 {
16268 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16269 widg->req_lstate_level = vbound(value/10000,-1,MAXLEVELS);
16270 break;
16271 }
16272 case SUBWIDGREQ_SCRSTATE_MAP:
16273 {
16274 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16275 widg->req_scrstate_map = vbound(value/10000,0,map_count);
16276 break;
16277 }
16278 case SUBWIDGREQ_SCRSTATE_SCREEN:
16279 {
16280 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16281 widg->req_scrstate_scr = vbound(value/10000,-1,MAPSCRSNORMAL-1);
16282 break;
16283 }
16284 case SUBWIDGREQSCRIPTDISABLED:
16285 {
16286 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16287 widg->is_disabled = value != 0;
16288 break;
16289 }
16290 ///---- ACTIVE SUBSCREENS ONLY
16291 case SUBWIDGSELECTORDSTX:
16292 {
16293 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16294 widg->selector_override.x = vbound(value/10000,-32768,32767);
16295 break;
16296 }
16297 case SUBWIDGSELECTORDSTY:
16298 {
16299 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16300 widg->selector_override.y = vbound(value/10000,-32768,32767);
16301 break;
16302 }
16303 case SUBWIDGSELECTORDSTW:
16304 {
16305 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16306 widg->selector_override.w = vbound(value/10000,-32768,32767);
16307 break;
16308 }
16309 case SUBWIDGSELECTORDSTH:
16310 {
16311 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16312 widg->selector_override.h = vbound(value/10000,-32768,32767);
16313 break;
16314 }
16315
16316 case SUBWIDGPRESSSCRIPT:
16317 {
16318 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16319 widg->generic_script = vbound(value/10000,0,NUMSCRIPTSGENERIC-1);
16320 break;
16321 }
16322 case SUBWIDGPGMODE:
16323 {
16324 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16325 widg->pg_mode = vbound(value/10000,0,PGGOTO_MAX-1);
16326 break;
16327 }
16328 case SUBWIDGPGTARG:
16329 {
16330 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16331 widg->pg_targ = vbound(value/10000,0,MAX_SUBSCR_PAGES-1);
16332 break;
16333 }
16334
16335 case SUBWIDGTRANSPGTY:
16336 {
16337 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16338 {
16339 auto& trans = widg->pg_trans;
16340 trans.type = vbound(value/10000,0,sstrMAX-1);
16341 }
16342 break;
16343 }
16344 case SUBWIDGTRANSPGSFX:
16345 {
16346 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref), {sstACTIVE, sstMAP}))
16347 {
16348 auto& trans = widg->pg_trans;
16349 trans.tr_sfx = vbound(value/10000,0,255);
16350 }
16351 break;
16352 }
16353 case SUBWIDGTY_FONT:
16354 {
16355 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16356 {
16357 auto val = vbound(value/10000,0,font_max-1);
16358 auto ty = widg->getType();
16359 switch(ty)
16360 {
16361 case widgTEXT:
16362 ((SW_Text*)widg)->fontid = val;
16363 break;
16364 case widgITMCOOLDOWNTEXT:
16365 ((SW_ItemCooldownText*)widg)->fontid = val;
16366 break;
16367 case widgTEXTBOX:
16368 ((SW_TextBox*)widg)->fontid = val;
16369 break;
16370 case widgSELECTEDTEXT:
16371 ((SW_SelectedText*)widg)->fontid = val;
16372 break;
16373 case widgTIME:
16374 ((SW_Time*)widg)->fontid = val;
16375 break;
16376 case widgCOUNTER:
16377 ((SW_Counter*)widg)->fontid = val;
16378 break;
16379 case widgBTNCOUNTER:
16380 ((SW_BtnCounter*)widg)->fontid = val;
16381 break;
16382 case widgOLDCTR:
16383 ((SW_Counters*)widg)->fontid = val;
16384 break;
16385 case widgMMAPTITLE:
16386 ((SW_MMapTitle*)widg)->fontid = val;
16387 break;
16388 default:
16389 bad_subwidg_type(false, ty);
16390 break;
16391 }
16392 }
16393 break;
16394 }
16395 case SUBWIDGTY_ALIGN:
16396 {
16397 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16398 {
16399 auto val = vbound(value/10000,0,sstaMAX-1);
16400 auto ty = widg->getType();
16401 switch(ty)
16402 {
16403 case widgTEXT:
16404 ((SW_Text*)widg)->align = val;
16405 break;
16406 case widgITMCOOLDOWNTEXT:
16407 ((SW_ItemCooldownText*)widg)->align = val;
16408 break;
16409 case widgTEXTBOX:
16410 ((SW_TextBox*)widg)->align = val;
16411 break;
16412 case widgSELECTEDTEXT:
16413 ((SW_SelectedText*)widg)->align = val;
16414 break;
16415 case widgTIME:
16416 ((SW_Time*)widg)->align = val;
16417 break;
16418 case widgCOUNTER:
16419 ((SW_Counter*)widg)->align = val;
16420 break;
16421 case widgBTNCOUNTER:
16422 ((SW_BtnCounter*)widg)->align = val;
16423 break;
16424 case widgMMAPTITLE:
16425 ((SW_MMapTitle*)widg)->align = val;
16426 break;
16427 default:
16428 bad_subwidg_type(false, ty);
16429 break;
16430 }
16431 }
16432 break;
16433 }
16434 case SUBWIDGTY_SHADOWTY:
16435 {
16436 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16437 {
16438 auto val = vbound(value/10000,0,sstsMAX-1);
16439 auto ty = widg->getType();
16440 switch(ty)
16441 {
16442 case widgTEXT:
16443 ((SW_Text*)widg)->shadtype = val;
16444 break;
16445 case widgITMCOOLDOWNTEXT:
16446 ((SW_ItemCooldownText*)widg)->shadtype = val;
16447 break;
16448 case widgTEXTBOX:
16449 ((SW_TextBox*)widg)->shadtype = val;
16450 break;
16451 case widgSELECTEDTEXT:
16452 ((SW_SelectedText*)widg)->shadtype = val;
16453 break;
16454 case widgTIME:
16455 ((SW_Time*)widg)->shadtype = val;
16456 break;
16457 case widgCOUNTER:
16458 ((SW_Counter*)widg)->shadtype = val;
16459 break;
16460 case widgBTNCOUNTER:
16461 ((SW_BtnCounter*)widg)->shadtype = val;
16462 break;
16463 case widgOLDCTR:
16464 ((SW_Counters*)widg)->shadtype = val;
16465 break;
16466 case widgMMAPTITLE:
16467 ((SW_MMapTitle*)widg)->shadtype = val;
16468 break;
16469 default:
16470 bad_subwidg_type(false, ty);
16471 break;
16472 }
16473 }
16474 break;
16475 }
16476 case SUBWIDGTY_COLOR_TXT:
16477 {
16478 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16479 {
16480 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16481 auto ty = widg->getType();
16482 switch(ty)
16483 {
16484 case widgTEXT:
16485 ((SW_Text*)widg)->c_text.set_int_color(val);
16486 break;
16487 case widgITMCOOLDOWNTEXT:
16488 ((SW_ItemCooldownText*)widg)->c_text.set_int_color(val);
16489 break;
16490 case widgTEXTBOX:
16491 ((SW_TextBox*)widg)->c_text.set_int_color(val);
16492 break;
16493 case widgSELECTEDTEXT:
16494 ((SW_SelectedText*)widg)->c_text.set_int_color(val);
16495 break;
16496 case widgTIME:
16497 ((SW_Time*)widg)->c_text.set_int_color(val);
16498 break;
16499 case widgCOUNTER:
16500 ((SW_Counter*)widg)->c_text.set_int_color(val);
16501 break;
16502 case widgBTNCOUNTER:
16503 ((SW_BtnCounter*)widg)->c_text.set_int_color(val);
16504 break;
16505 case widgOLDCTR:
16506 ((SW_Counters*)widg)->c_text.set_int_color(val);
16507 break;
16508 case widgMMAPTITLE:
16509 ((SW_MMapTitle*)widg)->c_text.set_int_color(val);
16510 break;
16511 case widgMCGUFF_FRAME:
16512 ((SW_TriFrame*)widg)->c_number.set_int_color(val);
16513 break;
16514 default:
16515 bad_subwidg_type(false, ty);
16516 break;
16517 }
16518 }
16519 break;
16520 }
16521 case SUBWIDGTY_COLOR_SHD:
16522 {
16523 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16524 {
16525 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16526 auto ty = widg->getType();
16527 switch(ty)
16528 {
16529 case widgTEXT:
16530 ((SW_Text*)widg)->c_shadow.set_int_color(val);
16531 break;
16532 case widgITMCOOLDOWNTEXT:
16533 ((SW_ItemCooldownText*)widg)->c_shadow.set_int_color(val);
16534 break;
16535 case widgTEXTBOX:
16536 ((SW_TextBox*)widg)->c_shadow.set_int_color(val);
16537 break;
16538 case widgSELECTEDTEXT:
16539 ((SW_SelectedText*)widg)->c_shadow.set_int_color(val);
16540 break;
16541 case widgTIME:
16542 ((SW_Time*)widg)->c_shadow.set_int_color(val);
16543 break;
16544 case widgCOUNTER:
16545 ((SW_Counter*)widg)->c_shadow.set_int_color(val);
16546 break;
16547 case widgBTNCOUNTER:
16548 ((SW_BtnCounter*)widg)->c_shadow.set_int_color(val);
16549 break;
16550 case widgOLDCTR:
16551 ((SW_Counters*)widg)->c_shadow.set_int_color(val);
16552 break;
16553 case widgMMAPTITLE:
16554 ((SW_MMapTitle*)widg)->c_shadow.set_int_color(val);
16555 break;
16556 default:
16557 bad_subwidg_type(false, ty);
16558 break;
16559 }
16560 }
16561 break;
16562 }
16563 case SUBWIDGTY_COLOR_BG:
16564 {
16565 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16566 {
16567 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16568 auto ty = widg->getType();
16569 switch(ty)
16570 {
16571 case widgTEXT:
16572 ((SW_Text*)widg)->c_bg.set_int_color(val);
16573 break;
16574 case widgITMCOOLDOWNTEXT:
16575 ((SW_ItemCooldownText*)widg)->c_bg.set_int_color(val);
16576 break;
16577 case widgTEXTBOX:
16578 ((SW_TextBox*)widg)->c_bg.set_int_color(val);;
16579 break;
16580 case widgSELECTEDTEXT:
16581 ((SW_SelectedText*)widg)->c_bg.set_int_color(val);;
16582 break;
16583 case widgTIME:
16584 ((SW_Time*)widg)->c_bg.set_int_color(val);
16585 break;
16586 case widgCOUNTER:
16587 ((SW_Counter*)widg)->c_bg.set_int_color(val);
16588 break;
16589 case widgBTNCOUNTER:
16590 ((SW_BtnCounter*)widg)->c_bg.set_int_color(val);
16591 break;
16592 case widgOLDCTR:
16593 ((SW_Counters*)widg)->c_bg.set_int_color(val);
16594 break;
16595 case widgMMAPTITLE:
16596 ((SW_MMapTitle*)widg)->c_bg.set_int_color(val);
16597 break;
16598 case widgBGCOLOR:
16599 ((SW_Clear*)widg)->c_bg.set_int_color(val);
16600 break;
16601 case widgCOUNTERPERCBAR:
16602 ((SW_CounterPercentBar*)widg)->c_bg.set_int_color(val);
16603 break;
16604 default:
16605 bad_subwidg_type(false, ty);
16606 break;
16607 }
16608 }
16609 break;
16610 }
16611
16612 case SUBWIDGTY_COLOR_TXT2:
16613 {
16614 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16615 {
16616 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16617 auto ty = widg->getType();
16618 switch(ty)
16619 {
16620 case widgCOUNTER:
16621 ((SW_Counter*)widg)->c_text2.set_int_color(val);
16622 break;
16623 case widgBTNCOUNTER:
16624 ((SW_BtnCounter*)widg)->c_text2.set_int_color(val);
16625 break;
16626 default:
16627 bad_subwidg_type(false, ty);
16628 break;
16629 }
16630 }
16631 break;
16632 }
16633 case SUBWIDGTY_COLOR_SHD2:
16634 {
16635 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16636 {
16637 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16638 auto ty = widg->getType();
16639 switch(ty)
16640 {
16641 case widgCOUNTER:
16642 ((SW_Counter*)widg)->c_shadow2.set_int_color(val);
16643 break;
16644 case widgBTNCOUNTER:
16645 ((SW_BtnCounter*)widg)->c_shadow2.set_int_color(val);
16646 break;
16647 default:
16648 bad_subwidg_type(false, ty);
16649 break;
16650 }
16651 }
16652 break;
16653 }
16654 case SUBWIDGTY_COLOR_BG2:
16655 {
16656 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16657 {
16658 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16659 auto ty = widg->getType();
16660 switch(ty)
16661 {
16662 case widgCOUNTER:
16663 ((SW_Counter*)widg)->c_bg2.set_int_color(val);
16664 break;
16665 case widgBTNCOUNTER:
16666 ((SW_BtnCounter*)widg)->c_bg2.set_int_color(val);
16667 break;
16668 default:
16669 bad_subwidg_type(false, ty);
16670 break;
16671 }
16672 }
16673 break;
16674 }
16675
16676 case SUBWIDGTY_COLOR_OLINE:
16677 {
16678 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16679 {
16680 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16681 auto ty = widg->getType();
16682 switch(ty)
16683 {
16684 case widgLINE:
16685 ((SW_Line*)widg)->c_line.set_int_color(val);
16686 break;
16687 case widgRECT:
16688 ((SW_Rect*)widg)->c_outline.set_int_color(val);
16689 break;
16690 case widgMCGUFF_FRAME:
16691 ((SW_TriFrame*)widg)->c_outline.set_int_color(val);
16692 break;
16693 default:
16694 bad_subwidg_type(false, ty);
16695 break;
16696 }
16697 }
16698 break;
16699 }
16700
16701 case SUBWIDGTY_COLOR_FILL:
16702 {
16703 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16704 {
16705 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16706 auto ty = widg->getType();
16707 switch(ty)
16708 {
16709 case widgRECT:
16710 ((SW_Rect*)widg)->c_fill.set_int_color(val);
16711 break;
16712 case widgCOUNTERPERCBAR:
16713 ((SW_CounterPercentBar*)widg)->c_fill.set_int_color(val);
16714 break;
16715 default:
16716 bad_subwidg_type(false, ty);
16717 break;
16718 }
16719 }
16720 break;
16721 }
16722 case SUBWIDGTY_BUTTON:
16723 {
16724 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16725 {
16726 auto val = vbound(value/10000,-1,3);
16727 auto ty = widg->getType();
16728 switch(ty)
16729 {
16730 case widgBTNITM:
16731 ((SW_ButtonItem*)widg)->btn = zc_max(0, val);
16732 break;
16733 case widgBTNCOUNTER:
16734 ((SW_BtnCounter*)widg)->btn = zc_max(0, val);
16735 break;
16736 case widgITMCOOLDOWNGAUGE:
16737 ((SW_ItemCooldownGauge*)widg)->button_id = val;
16738 break;
16739 case widgITMCOOLDOWNTEXT:
16740 ((SW_ItemCooldownText*)widg)->button_id = val;
16741 break;
16742 default:
16743 bad_subwidg_type(false, ty);
16744 break;
16745 }
16746 }
16747 break;
16748 }
16749 case SUBWIDGTY_MINDIG:
16750 {
16751 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16752 {
16753 auto val = vbound(value/10000,0,5);
16754 auto ty = widg->getType();
16755 switch(ty)
16756 {
16757 case widgCOUNTER:
16758 ((SW_Counter*)widg)->mindigits = val;
16759 break;
16760 case widgBTNCOUNTER:
16761 ((SW_BtnCounter*)widg)->mindigits = val;
16762 break;
16763 case widgOLDCTR:
16764 ((SW_Counters*)widg)->digits = val;
16765 break;
16766 default:
16767 bad_subwidg_type(false, ty);
16768 break;
16769 }
16770 }
16771 break;
16772 }
16773 case SUBWIDGTY_MAXDIG:
16774 {
16775 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16776 {
16777 auto val = vbound(value/10000,0,5);
16778 auto ty = widg->getType();
16779 switch(ty)
16780 {
16781 case widgCOUNTER:
16782 ((SW_Counter*)widg)->maxdigits = val;
16783 break;
16784 case widgBTNCOUNTER:
16785 ((SW_BtnCounter*)widg)->maxdigits = val;
16786 break;
16787 default:
16788 bad_subwidg_type(false, ty);
16789 break;
16790 }
16791 }
16792 break;
16793 }
16794 case SUBWIDGTY_INFITM:
16795 {
16796 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16797 {
16798 auto val = vbound(value/10000,-1,MAXITEMS-1);
16799 auto ty = widg->getType();
16800 switch(ty)
16801 {
16802 case widgCOUNTER:
16803 ((SW_Counter*)widg)->infitm = val;
16804 break;
16805 case widgOLDCTR:
16806 ((SW_Counters*)widg)->infitm = val;
16807 break;
16808 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE:
16809 ((SW_GaugePiece*)widg)->inf_item = val;
16810 break;
16811 case widgITMCOOLDOWNGAUGE:
16812 default:
16813 bad_subwidg_type(false, ty);
16814 break;
16815 }
16816 }
16817 break;
16818 }
16819 case SUBWIDGTY_INFCHAR:
16820 {
16821 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16822 {
16823 char val = vbound(value/10000,0,255);
16824 auto ty = widg->getType();
16825 switch(ty)
16826 {
16827 case widgCOUNTER:
16828 ((SW_Counter*)widg)->infchar = val;
16829 break;
16830 case widgBTNCOUNTER:
16831 ((SW_BtnCounter*)widg)->infchar = val;
16832 break;
16833 case widgOLDCTR:
16834 ((SW_Counters*)widg)->infchar = val;
16835 break;
16836 default:
16837 bad_subwidg_type(false, ty);
16838 break;
16839 }
16840 }
16841 break;
16842 }
16843 case SUBWIDGTY_COSTIND:
16844 {
16845 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16846 {
16847 auto val = vbound(value/10000,0,1);
16848 auto ty = widg->getType();
16849 switch(ty)
16850 {
16851 case widgBTNCOUNTER:
16852 ((SW_BtnCounter*)widg)->costind = val;
16853 break;
16854 default:
16855 bad_subwidg_type(false, ty);
16856 break;
16857 }
16858 }
16859 break;
16860 }
16861 case SUBWIDGTY_COLOR_PLAYER:
16862 {
16863 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16864 {
16865 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16866 auto ty = widg->getType();
16867 switch(ty)
16868 {
16869 case widgMMAP:
16870 ((SW_MMap*)widg)->c_plr.set_int_color(val);
16871 break;
16872 case widgLMAP:
16873 ((SW_LMap*)widg)->c_plr.set_int_color(val);
16874 break;
16875 default:
16876 bad_subwidg_type(false, ty);
16877 break;
16878 }
16879 }
16880 break;
16881 }
16882 case SUBWIDGTY_COLOR_CMPBLNK:
16883 {
16884 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16885 {
16886 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16887 auto ty = widg->getType();
16888 switch(ty)
16889 {
16890 case widgMMAP:
16891 ((SW_MMap*)widg)->c_cmp_blink.set_int_color(val);
16892 break;
16893 default:
16894 bad_subwidg_type(false, ty);
16895 break;
16896 }
16897 }
16898 break;
16899 }
16900 case SUBWIDGTY_COLOR_CMPOFF:
16901 {
16902 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16903 {
16904 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16905 auto ty = widg->getType();
16906 switch(ty)
16907 {
16908 case widgMMAP:
16909 ((SW_MMap*)widg)->c_cmp_off.set_int_color(val);
16910 break;
16911 default:
16912 bad_subwidg_type(false, ty);
16913 break;
16914 }
16915 }
16916 break;
16917 }
16918 case SUBWIDGTY_COLOR_ROOM:
16919 {
16920 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16921 {
16922 auto val = vbound(value/10000,MIN_SUBSCR_COLOR,MAX_SUBSCR_COLOR);
16923 auto ty = widg->getType();
16924 switch(ty)
16925 {
16926 case widgLMAP:
16927 ((SW_LMap*)widg)->c_room.set_int_color(val);
16928 break;
16929 default:
16930 bad_subwidg_type(false, ty);
16931 break;
16932 }
16933 }
16934 break;
16935 }
16936 case SUBWIDGTY_ITEMCLASS:
16937 {
16938 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16939 {
16940 auto val = vbound(value/10000,0,itype_maxusable-1);
16941 auto ty = widg->getType();
16942 switch(ty)
16943 {
16944 case widgITEMSLOT:
16945 ((SW_ItemSlot*)widg)->iclass = val;
16946 break;
16947 case widgITMCOOLDOWNGAUGE:
16948 ((SW_ItemCooldownGauge*)widg)->item_class = val;
16949 break;
16950 case widgITMCOOLDOWNTEXT:
16951 ((SW_ItemCooldownText*)widg)->item_class = val;
16952 break;
16953 default:
16954 bad_subwidg_type(false, ty);
16955 break;
16956 }
16957 }
16958 break;
16959 }
16960 case SUBWIDGTY_ITEMID:
16961 {
16962 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16963 {
16964 auto val = vbound(value/10000,-1,MAXITEMS-1);
16965 auto ty = widg->getType();
16966 switch(ty)
16967 {
16968 case widgITEMSLOT:
16969 ((SW_ItemSlot*)widg)->iid = val;
16970 break;
16971 case widgITMCOOLDOWNGAUGE:
16972 ((SW_ItemCooldownGauge*)widg)->specific_item_id = val;
16973 break;
16974 case widgITMCOOLDOWNTEXT:
16975 ((SW_ItemCooldownText*)widg)->specific_item_id = val;
16976 break;
16977 default:
16978 bad_subwidg_type(false, ty);
16979 break;
16980 }
16981 }
16982 break;
16983 }
16984 case SUBWIDGTY_FRAMETILE:
16985 {
16986 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
16987 {
16988 auto val = vbound(value/10000,0,NEWMAXTILES-1);
16989 auto ty = widg->getType();
16990 switch(ty)
16991 {
16992 case widgMCGUFF_FRAME:
16993 ((SW_TriFrame*)widg)->frame_tile = val;
16994 break;
16995 default:
16996 bad_subwidg_type(false, ty);
16997 break;
16998 }
16999 }
17000 break;
17001 }
17002 case SUBWIDGTY_FRAMECSET:
17003 {
17004 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17005 {
17006 auto val = vbound(value/10000,0,15);
17007 auto ty = widg->getType();
17008 switch(ty)
17009 {
17010 case widgMCGUFF_FRAME:
17011 ((SW_TriFrame*)widg)->frame_cset = val;
17012 break;
17013 default:
17014 bad_subwidg_type(false, ty);
17015 break;
17016 }
17017 }
17018 break;
17019 }
17020 case SUBWIDGTY_PIECETILE:
17021 {
17022 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17023 {
17024 auto val = vbound(value/10000,0,NEWMAXTILES-1);
17025 auto ty = widg->getType();
17026 switch(ty)
17027 {
17028 case widgMCGUFF_FRAME:
17029 ((SW_TriFrame*)widg)->piece_tile = val;
17030 break;
17031 default:
17032 bad_subwidg_type(false, ty);
17033 break;
17034 }
17035 }
17036 break;
17037 }
17038 case SUBWIDGTY_PIECECSET:
17039 {
17040 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17041 {
17042 auto val = vbound(value/10000,0,15);
17043 auto ty = widg->getType();
17044 switch(ty)
17045 {
17046 case widgMCGUFF_FRAME:
17047 ((SW_TriFrame*)widg)->piece_cset = val;
17048 break;
17049 default:
17050 bad_subwidg_type(false, ty);
17051 break;
17052 }
17053 }
17054 break;
17055 }
17056 case SUBWIDGTY_FLIP:
17057 {
17058 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17059 {
17060 auto val = vbound(value/10000,0,15);
17061 auto ty = widg->getType();
17062 switch(ty)
17063 {
17064 case widgMCGUFF:
17065 ((SW_McGuffin*)widg)->flip = val;
17066 break;
17067 case widgTILEBLOCK:
17068 ((SW_TileBlock*)widg)->flip = val;
17069 break;
17070 case widgMINITILE:
17071 ((SW_MiniTile*)widg)->flip = val;
17072 break;
17073 default:
17074 bad_subwidg_type(false, ty);
17075 break;
17076 }
17077 }
17078 break;
17079 }
17080 case SUBWIDGTY_NUMBER:
17081 {
17082 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17083 {
17084 auto val = vbound(value/10000,0,255);
17085 auto ty = widg->getType();
17086 switch(ty)
17087 {
17088 case widgMCGUFF:
17089 ((SW_McGuffin*)widg)->number = val;
17090 break;
17091 default:
17092 bad_subwidg_type(false, ty);
17093 break;
17094 }
17095 }
17096 break;
17097 }
17098 case SUBWIDGTY_FRAMES:
17099 {
17100 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17101 {
17102 auto val = vbound(value/10000,1,65535);
17103 auto ty = widg->getType();
17104 switch(ty)
17105 {
17106 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17107 ((SW_GaugePiece*)widg)->frames = val;
17108 break;
17109 default:
17110 bad_subwidg_type(false, ty);
17111 break;
17112 }
17113 }
17114 break;
17115 }
17116 case SUBWIDGTY_SPEED:
17117 {
17118 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17119 {
17120 auto val = vbound(value/10000,1,65535);
17121 auto ty = widg->getType();
17122 switch(ty)
17123 {
17124 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17125 ((SW_GaugePiece*)widg)->speed = val;
17126 break;
17127 default:
17128 bad_subwidg_type(false, ty);
17129 break;
17130 }
17131 }
17132 break;
17133 }
17134 case SUBWIDGTY_DELAY:
17135 {
17136 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17137 {
17138 auto val = vbound(value/10000,0,65535);
17139 auto ty = widg->getType();
17140 switch(ty)
17141 {
17142 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17143 ((SW_GaugePiece*)widg)->delay = val;
17144 break;
17145 default:
17146 bad_subwidg_type(false, ty);
17147 break;
17148 }
17149 }
17150 break;
17151 }
17152 case SUBWIDGTY_CONTAINER:
17153 {
17154 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17155 {
17156 auto val = vbound(value/10000,0,65535);
17157 auto ty = widg->getType();
17158 switch(ty)
17159 {
17160 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17161 ((SW_GaugePiece*)widg)->container = val;
17162 break;
17163 default:
17164 bad_subwidg_type(false, ty);
17165 break;
17166 }
17167 }
17168 break;
17169 }
17170 case SUBWIDGTY_GAUGE_WID:
17171 {
17172 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17173 {
17174 auto val = vbound(value/10000,1,32)-1;
17175 auto ty = widg->getType();
17176 switch(ty)
17177 {
17178 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17179 ((SW_GaugePiece*)widg)->gauge_wid = val;
17180 break;
17181 default:
17182 bad_subwidg_type(false, ty);
17183 break;
17184 }
17185 }
17186 break;
17187 }
17188 case SUBWIDGTY_GAUGE_HEI:
17189 {
17190 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17191 {
17192 auto val = vbound(value/10000,1,32)-1;
17193 auto ty = widg->getType();
17194 switch(ty)
17195 {
17196 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17197 ((SW_GaugePiece*)widg)->gauge_hei = val;
17198 break;
17199 default:
17200 bad_subwidg_type(false, ty);
17201 break;
17202 }
17203 }
17204 break;
17205 }
17206 case SUBWIDGTY_UNITS:
17207 {
17208 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17209 {
17210 auto val = vbound(value/10000,1,256);
17211 auto ty = widg->getType();
17212 switch(ty)
17213 {
17214 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17215 ((SW_GaugePiece*)widg)->unit_per_frame = val-1;
17216 break;
17217 default:
17218 bad_subwidg_type(false, ty);
17219 break;
17220 }
17221 }
17222 break;
17223 }
17224 case SUBWIDGTY_HSPACE:
17225 {
17226 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17227 {
17228 auto val = vbound(value/10000,-128,127);
17229 auto ty = widg->getType();
17230 switch(ty)
17231 {
17232 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17233 ((SW_GaugePiece*)widg)->hspace = val;
17234 break;
17235 default:
17236 bad_subwidg_type(false, ty);
17237 break;
17238 }
17239 }
17240 break;
17241 }
17242 case SUBWIDGTY_VSPACE:
17243 {
17244 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17245 {
17246 auto val = vbound(value/10000,-128,127);
17247 auto ty = widg->getType();
17248 switch(ty)
17249 {
17250 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17251 ((SW_GaugePiece*)widg)->vspace = val;
17252 break;
17253 default:
17254 bad_subwidg_type(false, ty);
17255 break;
17256 }
17257 }
17258 break;
17259 }
17260 case SUBWIDGTY_GRIDX:
17261 {
17262 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17263 {
17264 auto val = vbound(value/10000,-32768,32767);
17265 auto ty = widg->getType();
17266 switch(ty)
17267 {
17268 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17269 ((SW_GaugePiece*)widg)->grid_xoff = val;
17270 break;
17271 default:
17272 bad_subwidg_type(false, ty);
17273 break;
17274 }
17275 }
17276 break;
17277 }
17278 case SUBWIDGTY_GRIDY:
17279 {
17280 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17281 {
17282 auto val = vbound(value/10000,-32768,32767);
17283 auto ty = widg->getType();
17284 switch(ty)
17285 {
17286 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17287 ((SW_GaugePiece*)widg)->grid_yoff = val;
17288 break;
17289 default:
17290 bad_subwidg_type(false, ty);
17291 break;
17292 }
17293 }
17294 break;
17295 }
17296 case SUBWIDGTY_ANIMVAL:
17297 {
17298 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17299 {
17300 auto val = vbound(value/10000,0,65535);
17301 auto ty = widg->getType();
17302 switch(ty)
17303 {
17304 case widgLGAUGE: case widgMGAUGE: case widgMISCGAUGE: case widgITMCOOLDOWNGAUGE:
17305 ((SW_GaugePiece*)widg)->anim_val = val;
17306 break;
17307 default:
17308 bad_subwidg_type(false, ty);
17309 break;
17310 }
17311 }
17312 break;
17313 }
17314 case SUBWIDGTY_SHOWDRAIN:
17315 {
17316 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17317 {
17318 auto val = vbound(value/10000,-1,32767);
17319 auto ty = widg->getType();
17320 switch(ty)
17321 {
17322 case widgMGAUGE:
17323 ((SW_MagicGaugePiece*)widg)->showdrain = val;
17324 break;
17325 default:
17326 bad_subwidg_type(false, ty);
17327 break;
17328 }
17329 }
17330 break;
17331 }
17332 case SUBWIDGTY_PERCONTAINER:
17333 {
17334 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17335 {
17336 auto val = zc_max(value/10000,1);
17337 auto ty = widg->getType();
17338 switch(ty)
17339 {
17340 case widgMISCGAUGE:
17341 ((SW_MiscGaugePiece*)widg)->per_container = val;
17342 break;
17343 case widgITMCOOLDOWNGAUGE:
17344 ((SW_ItemCooldownGauge*)widg)->per_container = val;
17345 break;
17346 default:
17347 bad_subwidg_type(false, ty);
17348 break;
17349 }
17350 }
17351 break;
17352 }
17353 case SUBWIDGTY_TOTAL:
17354 {
17355 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17356 {
17357 auto val = zc_max(value/10000,1);
17358 auto ty = widg->getType();
17359 switch(ty)
17360 {
17361 case widgITMCOOLDOWNGAUGE:
17362 ((SW_ItemCooldownGauge*)widg)->total_points = val;
17363 break;
17364 default:
17365 bad_subwidg_type(false, ty);
17366 break;
17367 }
17368 }
17369 break;
17370 }
17371 case SUBWIDGTY_TABSIZE:
17372 {
17373 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17374 {
17375 auto val = vbound(value/10000,0,255);
17376 auto ty = widg->getType();
17377 switch(ty)
17378 {
17379 case widgTEXTBOX:
17380 ((SW_TextBox*)widg)->tabsize = val;
17381 break;
17382 case widgSELECTEDTEXT:
17383 ((SW_SelectedText*)widg)->tabsize = val;
17384 break;
17385 default:
17386 bad_subwidg_type(false, ty);
17387 break;
17388 }
17389 }
17390 break;
17391 }
17392 case SUBWIDGTY_LITEMS:
17393 {
17394 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
17395 {
17396 auto val = vbound(value/10000,0,255);
17397 auto ty = widg->getType();
17398 switch(ty)
17399 {
17400 case widgMMAP:
17401 ((SW_MMap*)widg)->compass_litems = val;
17402 break;
17403 default:
17404 bad_subwidg_type(false, ty);
17405 break;
17406 }
17407 }
17408 break;
17409 }
17410
17411 default:
17412 {
17413
2/2
✓ Branch 0 taken 18557789 times.
✓ Branch 1 taken 29352318 times.
47910107 if (zasm_array_supports(arg))
17414 {
17415 18557789 int ref_arg = get_register_ref_dependency(arg).value_or(0);
17416 #ifdef DEBUG_REGISTER_DEPS
17417 if (ref_arg) debug_get_ref(ref_arg);
17418 #endif
17419
2/2
✓ Branch 0 taken 10242338 times.
✓ Branch 1 taken 8315451 times.
18557789 int ref = ref_arg ? get_ref(ref_arg) : 0;
17420 18557789 zasm_array_set(arg, ref, GET_D(rINDEX) / 10000, value);
17421 18557789 }
17422 else
17423 {
17424 29352318 scripting_engine_set_register(arg, value);
17425 }
17426 }
17427 47910107 }
17428
17429 1817366519 current_zasm_register = 0;
17430 2462424054 } //end set_register
17431
17432 427 static std::map<std::string, int> name_to_slot_index_ffcmap;
17433 427 static std::map<std::string, int> name_to_slot_index_globalmap;
17434 427 static std::map<std::string, int> name_to_slot_index_genericmap;
17435 427 static std::map<std::string, int> name_to_slot_index_itemmap;
17436 427 static std::map<std::string, int> name_to_slot_index_npcmap;
17437 427 static std::map<std::string, int> name_to_slot_index_ewpnmap;
17438 427 static std::map<std::string, int> name_to_slot_index_lwpnmap;
17439 427 static std::map<std::string, int> name_to_slot_index_playermap;
17440 427 static std::map<std::string, int> name_to_slot_index_dmapmap;
17441 427 static std::map<std::string, int> name_to_slot_index_screenmap;
17442 427 static std::map<std::string, int> name_to_slot_index_itemspritemap;
17443 427 static std::map<std::string, int> name_to_slot_index_comboscriptmap;
17444 427 static std::map<std::string, int> name_to_slot_index_subscreenmap;
17445
17446 435 void script_init_name_to_slot_index_maps()
17447 {
17448 int i;
17449 #define DECL_INIT_MAP(name) \
17450 {\
17451 name_to_slot_index_##name.clear();\
17452 i = 0;\
17453 for (auto& it : name)\
17454 {\
17455 if (!name_to_slot_index_##name.contains(it.second.scriptname))\
17456 name_to_slot_index_##name[it.second.scriptname] = i;\
17457 i++;\
17458 }\
17459 }
17460
17461
4/4
✓ Branch 0 taken 222285 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 211812 times.
✓ Branch 3 taken 10473 times.
222720 DECL_INIT_MAP(ffcmap);
17462
4/4
✓ Branch 0 taken 3480 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 1988 times.
✓ Branch 3 taken 1492 times.
3915 DECL_INIT_MAP(globalmap);
17463
4/4
✓ Branch 0 taken 222285 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 219512 times.
✓ Branch 3 taken 2773 times.
222720 DECL_INIT_MAP(genericmap);
17464
4/4
✓ Branch 0 taken 110925 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 109286 times.
✓ Branch 3 taken 1639 times.
111360 DECL_INIT_MAP(itemmap);
17465
4/4
✓ Branch 0 taken 110925 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 110327 times.
✓ Branch 3 taken 598 times.
111360 DECL_INIT_MAP(npcmap);
17466
4/4
✓ Branch 0 taken 110925 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 110161 times.
✓ Branch 3 taken 764 times.
111360 DECL_INIT_MAP(ewpnmap);
17467
4/4
✓ Branch 0 taken 110925 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 110143 times.
✓ Branch 3 taken 782 times.
111360 DECL_INIT_MAP(lwpnmap);
17468
4/4
✓ Branch 0 taken 1740 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 1272 times.
✓ Branch 3 taken 468 times.
2175 DECL_INIT_MAP(playermap);
17469
4/4
✓ Branch 0 taken 110925 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 109983 times.
✓ Branch 3 taken 942 times.
111360 DECL_INIT_MAP(dmapmap);
17470
4/4
✓ Branch 0 taken 110925 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 110132 times.
✓ Branch 3 taken 793 times.
111360 DECL_INIT_MAP(screenmap);
17471
4/4
✓ Branch 0 taken 110925 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 110437 times.
✓ Branch 3 taken 488 times.
111360 DECL_INIT_MAP(itemspritemap);
17472
4/4
✓ Branch 0 taken 222285 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 221684 times.
✓ Branch 3 taken 601 times.
222720 DECL_INIT_MAP(comboscriptmap);
17473
4/4
✓ Branch 0 taken 110925 times.
✓ Branch 1 taken 435 times.
✓ Branch 2 taken 110475 times.
✓ Branch 3 taken 450 times.
111360 DECL_INIT_MAP(subscreenmap);
17474 435 }
17475
17476 10256680 static void do_get_script_index_by_name(const std::map<std::string, int>& name_to_slot_index)
17477 {
17478 10256680 int32_t arrayptr = get_register(sarg1);
17479 10256680 string name;
17480 10256680 int32_t num=-1;
17481
1/2
✓ Branch 0 taken 10256680 times.
✗ Branch 1 not taken.
10256680 ArrayH::getString(arrayptr, name, 256); // What's the limit on name length?
17482
17483
1/2
✓ Branch 0 taken 10256680 times.
✗ Branch 1 not taken.
10256680 auto it = name_to_slot_index.find(name);
17484
2/2
✓ Branch 0 taken 8430579 times.
✓ Branch 1 taken 1826101 times.
10256680 if (it != name_to_slot_index.end())
17485 1826101 num = it->second + 1;
17486
17487
1/2
✓ Branch 0 taken 10256680 times.
✗ Branch 1 not taken.
10256680 set_register(sarg1, num * 10000);
17488 10256680 }
17489
17490 ///----------------------------------------------------------------------------------------------------//
17491 // ASM Functions //
17492 ///----------------------------------------------------------------------------------------------------//
17493
17494 48376 bool check_stack(uint32_t sp)
17495 {
17496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48376 times.
48376 if (sp >= MAX_STACK_SIZE)
17497 {
17498 log_stack_overflow_error();
17499 ri->overflow = true;
17500 return false;
17501 }
17502
17503 48376 return true;
17504 48376 }
17505
17506 2205627045 void retstack_push(int32_t val)
17507 {
17508
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2205627045 times.
2205627045 if(ri->retsp >= MAX_CALL_FRAMES)
17509 {
17510 log_call_limit_error();
17511 ri->overflow = true;
17512 return;
17513 }
17514 2205627045 (*ret_stack)[ri->retsp++] = val;
17515 2205627045 }
17516 2205580289 optional<int32_t> retstack_pop()
17517 {
17518
2/2
✓ Branch 0 taken 810 times.
✓ Branch 1 taken 2205579479 times.
2205580289 if(!ri->retsp)
17519 810 return nullopt; //return from root, so, QUIT
17520 2205579479 return (*ret_stack)[--ri->retsp];
17521 2205580289 }
17522
17523 21335980 void stack_push(int32_t val)
17524 {
17525 21335980 SH::write_stack(--ri->sp, val);
17526 21335980 }
17527 48376 void stack_push(int32_t val, size_t count)
17528 {
17529
1/2
✓ Branch 0 taken 48376 times.
✗ Branch 1 not taken.
48376 if (!check_stack(ri->sp - count))
17530 return;
17531
17532
2/2
✓ Branch 0 taken 48376 times.
✓ Branch 1 taken 246457 times.
294833 for(int q = 0; q < count; ++q)
17533 {
17534 246457 --ri->sp;
17535 246457 (*stack)[ri->sp] = val;
17536 246457 }
17537 48376 }
17538
17539 20713642 int32_t stack_pop()
17540 {
17541 20713642 const int32_t val = SH::read_stack(ri->sp);
17542 20713642 ++ri->sp;
17543 20713642 return val;
17544 }
17545 207868 int32_t stack_pop(size_t count)
17546 {
17547 207868 ri->sp += count;
17548 207868 const int32_t val = SH::read_stack(ri->sp-1);
17549 207868 return val;
17550 }
17551
17552 ///----------------------------------------------------------------------------------------------------//
17553 //Internal (to ZScript)
17554
17555 // Changing the script of the currently executing scriptable object is not supported.
17556 17149488 bool is_guarded_script_register(int reg)
17557 {
17558
2/2
✓ Branch 0 taken 17055338 times.
✓ Branch 1 taken 94150 times.
17149488 switch (reg)
17559 {
17560 case DMAPSCRIPT:
17561 case EWPNSCRIPT:
17562 case FFSCRIPT:
17563 case IDATAPSCRIPT:
17564 case IDATASCRIPT:
17565 case ITEMSPRITESCRIPT:
17566 case LWPNSCRIPT:
17567 case NPCSCRIPT:
17568 case SCREENSCRIPT:
17569 94150 return true;
17570 }
17571
17572 17055338 return false;
17573 17149488 }
17574
17575 16318583 void do_set(int reg, int value)
17576 {
17577
2/2
✓ Branch 0 taken 16227697 times.
✓ Branch 1 taken 90886 times.
16318583 if (!is_guarded_script_register(reg))
17578 {
17579 16227697 set_register(reg, value);
17580 16227697 return;
17581 }
17582
17583 90886 ScriptType whichType = curScriptType;
17584 90886 int32_t whichUID = curScriptIndex;
17585
17586 90886 bool allowed = true;
17587
8/9
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 60540 times.
✓ Branch 2 taken 18823 times.
✓ Branch 3 taken 5311 times.
✓ Branch 4 taken 1410 times.
✓ Branch 5 taken 1730 times.
✓ Branch 6 taken 3009 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 37 times.
90886 switch(whichType) //Check for objects attempting to change own script
17588 {
17589 //case ScriptType::Global:
17590
17591 case ScriptType::FFC:
17592
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 3353 times.
5311 if (reg == FFSCRIPT)
17593 {
17594
3/4
✓ Branch 0 taken 3353 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3185 times.
✓ Branch 3 taken 168 times.
3353 if (auto ffc = ResolveFFC(GET_REF(ffcref)); ffc && ffc->index == whichUID)
17595 168 allowed = false;
17596 3353 }
17597 5311 break;
17598
17599 case ScriptType::Screen:
17600
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if(reg==SCREENSCRIPT) //Only 1 screen script running at a time, no UID check needed
17601 allowed = false;
17602 26 break;
17603
17604 case ScriptType::Item:
17605 {
17606
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 1312 times.
1410 bool collect = ( ( whichUID < 1 ) || (whichUID == COLLECT_SCRIPT_ITEM_ZERO) );
17607
3/4
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 1312 times.
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
1410 int32_t new_UID = ( collect ) ? (( whichUID != COLLECT_SCRIPT_ITEM_ZERO ) ? (whichUID * -1) : 0) : whichUID;
17608
17609
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 1312 times.
1410 if(collect)
17610 {
17611
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
98 if(reg==IDATAPSCRIPT && ri->itemdataref==new_UID)
17612 allowed = false;
17613 98 }
17614
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1312 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1312 else if(reg==IDATASCRIPT && ri->itemdataref==new_UID)
17615 allowed = false;
17616 1410 break;
17617 }
17618
17619 case ScriptType::Lwpn:
17620
3/4
✓ Branch 0 taken 60516 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 60516 times.
✗ Branch 3 not taken.
60540 if(reg==LWPNSCRIPT && ri->lwpnref==whichUID)
17621 allowed = false;
17622 60540 break;
17623
17624 case ScriptType::NPC:
17625
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1730 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1730 if(reg==NPCSCRIPT && ri->npcref==whichUID)
17626 allowed = false;
17627 1730 break;
17628
17629 case ScriptType::Ewpn:
17630
3/4
✓ Branch 0 taken 2310 times.
✓ Branch 1 taken 699 times.
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
3009 if(reg==EWPNSCRIPT && ri->ewpnref==whichUID)
17631 allowed = false;
17632 3009 break;
17633
17634 case ScriptType::DMap:
17635 if(reg==DMAPSCRIPT && ri->dmapdataref==whichUID)
17636 allowed = false;
17637 break;
17638
17639 case ScriptType::ItemSprite:
17640
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
37 if(reg==ITEMSPRITESCRIPT && ri->itemref==whichUID)
17641 allowed = false;
17642 37 break;
17643 }
17644
17645
2/2
✓ Branch 0 taken 90718 times.
✓ Branch 1 taken 168 times.
90886 if (!allowed)
17646 {
17647 168 Z_scripterrlog("Script attempted to change own object's script! This has been ignored.\n");
17648 168 return;
17649 }
17650
17651 90718 set_register(reg, value);
17652 16318583 }
17653
17654 16227910 void do_set_command(const bool v)
17655 {
17656 16227910 int32_t temp = SH::get_arg(sarg2, v);
17657 16227910 do_set(sarg1, temp);
17658 16227910 }
17659
17660 21335980 void do_push(const bool v)
17661 {
17662 21335980 const int32_t value = SH::get_arg(sarg1, v);
17663 21335980 stack_push(value);
17664 21335980 }
17665 5343804 void do_push_varg(const bool v)
17666 {
17667 5343804 const int32_t value = SH::get_arg(sarg1, v);
17668 5343804 zs_vargs.push_back(value);
17669 5343804 }
17670
17671 2674 void do_push_vargs(const bool v)
17672 {
17673
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2674 times.
2674 if(sarg2 < 1) return;
17674 2674 const int value = SH::get_arg(sarg1, v);
17675 2674 zs_vargs.insert(zs_vargs.end(), sarg2, value);
17676 2674 zs_vargs.push_back(value);
17677 2674 }
17678
17679 20713642 void do_pop()
17680 {
17681 20713642 set_register(sarg1, stack_pop());
17682 20713642 }
17683
17684 void do_peek()
17685 {
17686 set_register(sarg1, SH::read_stack(ri->sp));
17687 }
17688
17689 void do_peekat(const bool v)
17690 {
17691 auto offs = SH::get_arg(sarg2,v);
17692 set_register(sarg1, SH::read_stack(ri->sp+offs));
17693 }
17694
17695 void do_writeat(const bool v1, const bool v2)
17696 {
17697 auto val = SH::get_arg(sarg1,v1);
17698 auto offs = SH::get_arg(sarg2,v2);
17699 SH::write_stack(ri->sp+offs, val);
17700 }
17701
17702 207868 void do_pops() // Pop past a bunch of stuff at once. Useful for clearing the stack.
17703 {
17704 207868 set_register(sarg1, stack_pop(sarg2));
17705 207868 }
17706
17707 48376 void do_pushs(const bool v) // Push a bunch of the same thing. Useful for filling the stack.
17708 {
17709 48376 const int value = SH::get_arg(sarg1, v);
17710 48376 stack_push(value, sarg2);
17711 48376 }
17712
17713 void do_loadi()
17714 {
17715 const int32_t stackoffset = get_register(sarg2) / 10000;
17716 const int32_t value = SH::read_stack(stackoffset);
17717 set_register(sarg1, value);
17718 }
17719
17720 void do_storei()
17721 {
17722 const int32_t stackoffset = get_register(sarg2) / 10000;
17723 const int32_t value = get_register(sarg1);
17724 SH::write_stack(stackoffset, value);
17725 }
17726
17727 void do_loadd()
17728 {
17729 const int32_t stackoffset = (sarg2+GET_D(rSFRAME)) / 10000;
17730 const int32_t value = SH::read_stack(stackoffset);
17731 set_register(sarg1, value);
17732 }
17733
17734 20119254 void do_load()
17735 {
17736 20119254 const int32_t stackoffset = GET_D(rSFRAME) + sarg2;
17737 20119254 const int32_t value = SH::read_stack(stackoffset);
17738 20119254 set_register(sarg1, value);
17739 20119254 }
17740
17741 4 static void do_load_internal_array()
17742 {
17743
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 CHECK(ZScriptVersion::gc_arrays());
17744
17745 4 auto array = find_or_create_internal_script_array({sarg2, 0});
17746
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 set_register(sarg1, array ? array->id : 0);
17747 4 }
17748
17749 22 static void do_load_internal_array_ref()
17750 {
17751
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 CHECK(ZScriptVersion::gc_arrays());
17752
17753 22 int ref = get_register(sarg3);
17754 22 auto array = find_or_create_internal_script_array({sarg2, ref});
17755
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 set_register(sarg1, array ? array->id : 0);
17756 22 }
17757
17758 void do_stored(const bool v)
17759 {
17760 const int32_t stackoffset = (sarg2+GET_D(rSFRAME)) / 10000;
17761 const int32_t value = SH::get_arg(sarg1, v);
17762 SH::write_stack(stackoffset, value);
17763 }
17764
17765 3465034 void do_store(const bool v)
17766 {
17767 3465034 const int32_t stackoffset = GET_D(rSFRAME) + sarg2;
17768 3465034 const int32_t value = SH::get_arg(sarg1, v);
17769 3465034 SH::write_stack(stackoffset, value);
17770 3465034 }
17771
17772 16792590 void script_store_object(uint32_t offset, uint32_t new_id)
17773 {
17774 DCHECK(offset < MAX_STACK_SIZE);
17775
17776 // Increase, then decrease, to handle the case where a variable (holding the only reference to an object) is assigned to itself.
17777 // This is unlikely so lets not bother with a conditional that skips both ref modifications when the ids are equal.
17778 16792590 uint32_t id = SH::read_stack(offset);
17779 16792590 script_object_ref_inc(new_id);
17780
2/2
✓ Branch 0 taken 683876 times.
✓ Branch 1 taken 16108714 times.
16792590 if (ri->stack_pos_is_object.contains(offset))
17781 683876 script_object_ref_dec(id);
17782 else
17783 16108714 ri->stack_pos_is_object.insert(offset);
17784
17785 16792590 SH::write_stack(offset, new_id);
17786
17787
2/2
✓ Branch 0 taken 14597110 times.
✓ Branch 1 taken 2195480 times.
16792590 if (util::remove_if_exists(script_object_autorelease_pool, new_id))
17788 2195480 script_object_ref_dec(new_id);
17789 16792590 }
17790
17791 void do_store_object(const bool v)
17792 {
17793 const int32_t stackoffset = GET_D(rSFRAME) + sarg2;
17794 const int32_t new_id = SH::get_arg(sarg1, v);
17795 script_store_object(stackoffset, new_id);
17796 }
17797
17798 19329308 void script_remove_object_ref(int32_t offset)
17799 {
17800
1/2
✓ Branch 0 taken 19329308 times.
✗ Branch 1 not taken.
19329308 if (offset < 0 || offset >= MAX_STACK_SIZE)
17801 {
17802 assert(false);
17803 return;
17804 }
17805
17806
2/2
✓ Branch 0 taken 1643460 times.
✓ Branch 1 taken 17685848 times.
19329308 if (!ri->stack_pos_is_object.contains(offset))
17807 1643460 return;
17808
17809 17685848 uint32_t id = SH::read_stack(offset);
17810 17685848 script_object_ref_dec(id);
17811 17685848 ri->stack_pos_is_object.erase(offset);
17812 19329308 }
17813
17814 10800384 void do_comp(bool v, const bool inv = false)
17815 {
17816 10800384 bool v2 = false;
17817
1/2
✓ Branch 0 taken 10800384 times.
✗ Branch 1 not taken.
10800384 if(inv) zc_swap(v,v2);
17818 10800384 ri->cmp_op2 = SH::get_arg(sarg2, v);
17819 10800384 ri->cmp_op1 = SH::get_arg(sarg1, v2);
17820 10800384 ri->cmp_strcache = nullopt;
17821 10800384 }
17822
17823 void do_internal_strcmp()
17824 {
17825 int32_t arrayptr_a = get_register(sarg1);
17826 int32_t arrayptr_b = get_register(sarg2);
17827 string strA;
17828 string strB;
17829 ArrayH::getString(arrayptr_a, strA);
17830 ArrayH::getString(arrayptr_b, strB);
17831 ri->cmp_strcache = strcmp(strA.c_str(), strB.c_str());
17832 }
17833
17834 void do_internal_stricmp()
17835 {
17836 int32_t arrayptr_a = get_register(sarg1);
17837 int32_t arrayptr_b = get_register(sarg2);
17838 string strA;
17839 string strB;
17840 ArrayH::getString(arrayptr_a, strA);
17841 ArrayH::getString(arrayptr_b, strB);
17842 ri->cmp_strcache = stricmp(strA.c_str(), strB.c_str());
17843 }
17844
17845 1621 void do_resize_array()
17846 {
17847 1621 int32_t size = vbound(get_register(sarg2) / 10000, 0, 214748);
17848 1621 dword ptrval = get_register(sarg1);
17849 1621 ArrayManager am(ptrval);
17850 1621 am.resize(size);
17851 1621 }
17852
17853 void do_own_array(int arrindx, ScriptType scriptType, const int32_t UID)
17854 {
17855 ArrayManager am(arrindx);
17856
17857 if(am.internal())
17858 {
17859 Z_scripterrlog_force_trace("Cannot 'OwnArray()' an internal array '%d'\n", arrindx);
17860 return;
17861 }
17862 if(arrindx >= NUM_ZSCRIPT_ARRAYS && arrindx < NUM_ZSCRIPT_ARRAYS*2)
17863 {
17864 //ignore global arrays
17865 }
17866 else if(!am.invalid())
17867 {
17868 if(arrindx > 0 && arrindx < NUM_ZSCRIPT_ARRAYS)
17869 {
17870 arrayOwner[arrindx].reown(scriptType, UID);
17871 arrayOwner[arrindx].specOwned = true;
17872 }
17873 else if(arrindx < 0) //object array
17874 Z_scripterrlog_force_trace("Cannot 'OwnArray()' an object-based array '%d'\n", arrindx);
17875 }
17876 else Z_scripterrlog_force_trace("Tried to 'OwnArray()' an invalid array '%d'\n", arrindx);
17877 }
17878
17879 void do_own_array(int arrindx, sprite* spr)
17880 {
17881 ArrayManager am(arrindx);
17882
17883 if(am.internal())
17884 {
17885 Z_scripterrlog_force_trace("Cannot 'OwnArray()' an internal array '%d'\n", arrindx);
17886 return;
17887 }
17888 if(arrindx >= NUM_ZSCRIPT_ARRAYS && arrindx < NUM_ZSCRIPT_ARRAYS*2)
17889 {
17890 //ignore global arrays
17891 }
17892 else if(!am.invalid())
17893 {
17894 if(arrindx > 0 && arrindx < NUM_ZSCRIPT_ARRAYS)
17895 {
17896 arrayOwner[arrindx].reown(spr);
17897 arrayOwner[arrindx].specOwned = true;
17898 }
17899 else if(arrindx < 0) //object array
17900 Z_scripterrlog_force_trace("Cannot 'OwnArray()' an object-based array '%d'\n", arrindx);
17901 }
17902 else Z_scripterrlog_force_trace("Tried to 'OwnArray()' an invalid array '%d'\n", arrindx);
17903 }
17904
17905 void do_destroy_array()
17906 {
17907 if (ZScriptVersion::gc_arrays())
17908 {
17909 scripting_log_error_with_context("Cannot force destroy arrays in 3.0+");
17910 return;
17911 }
17912
17913 int arrindx = get_register(sarg1);
17914
17915 ArrayManager am(arrindx);
17916
17917 if(am.internal())
17918 {
17919 Z_scripterrlog_force_trace("Cannot 'DestroyArray()' an internal array '%d'\n", arrindx);
17920 return;
17921 }
17922
17923 if(arrindx >= NUM_ZSCRIPT_ARRAYS && arrindx < NUM_ZSCRIPT_ARRAYS*2)
17924 {
17925 //ignore global arrays
17926 }
17927 else if(!am.invalid())
17928 {
17929 if(arrindx > 0 && arrindx < NUM_ZSCRIPT_ARRAYS)
17930 {
17931 arrayOwner[arrindx].clear();
17932
17933 if(localRAM[arrindx].Valid())
17934 localRAM[arrindx].Clear();
17935
17936 arrayOwner[arrindx].specCleared = true;
17937 }
17938 else if(arrindx < 0) //object array
17939 Z_scripterrlog_force_trace("Cannot 'DestroyArray()' an object-based array '%d'\n", arrindx);
17940 }
17941 else Z_scripterrlog_force_trace("Tried to 'DestroyArray()' an invalid array '%d'\n", arrindx);
17942 }
17943
17944 13698919 static dword allocatemem_old(int32_t size, bool local, ScriptType type, const uint32_t UID, script_object_type object_type)
17945 {
17946 dword ptrval;
17947
17948
1/2
✓ Branch 0 taken 13698919 times.
✗ Branch 1 not taken.
13698919 if(size < 0)
17949 {
17950 Z_scripterrlog_force_trace("Array initialized to invalid size of %d\n", size);
17951 return 0;
17952 }
17953
17954
2/2
✓ Branch 0 taken 13698125 times.
✓ Branch 1 taken 794 times.
13698919 if(local)
17955 {
17956 //localRAM[0] is used as an invalid container, so 0 can be the NULL pointer in ZScript
17957
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 446326904 times.
✓ Branch 2 taken 432628779 times.
✓ Branch 3 taken 13698125 times.
446326904 for(ptrval = 1; ptrval < NUM_ZSCRIPT_ARRAYS && localRAM[ptrval].Valid(); ptrval++) ;
17958
17959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13698125 times.
13698125 if(ptrval >= NUM_ZSCRIPT_ARRAYS)
17960 {
17961 Z_scripterrlog_force_trace("%d local arrays already in use, no more can be allocated\n", NUM_ZSCRIPT_ARRAYS-1);
17962 ptrval = 0;
17963 DCHECK(false);
17964 }
17965 else
17966 {
17967 13698125 ZScriptArray &a = localRAM[ptrval];
17968
17969 13698125 a.Resize(size);
17970 13698125 a.setValid(true);
17971 13698125 a.setObjectType(object_type);
17972
17973
2/2
✓ Branch 0 taken 211604475 times.
✓ Branch 1 taken 13698125 times.
225302600 for(dword j = 0; j < (dword)size; j++)
17974 211604475 a[j] = 0; //initialize array
17975
17976 // Keep track of which object created the array so we know which to deallocate
17977 13698125 arrayOwner[ptrval].clear();
17978 13698125 arrayOwner[ptrval].reown(type, UID);
17979 }
17980 13698125 }
17981 else
17982 {
17983 //Globals are only allocated here at first play, otherwise in init_game
17984
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24013 times.
✓ Branch 2 taken 23219 times.
✓ Branch 3 taken 794 times.
24013 for(ptrval = 0; ptrval < game->globalRAM.size() && game->globalRAM[ptrval].Valid(); ptrval++) ;
17985
17986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 794 times.
794 if(ptrval >= game->globalRAM.size())
17987 {
17988 Z_scripterrlog_force_trace("Invalid pointer value of %u passed to global allocate\n", ptrval);
17989 ptrval = 0;
17990 //this shouldn't happen, unless people are putting ALLOCATEGMEM in their ZASM scripts where they shouldn't be
17991 DCHECK(false);
17992 return ptrval * 10000;
17993 }
17994
17995 794 ZScriptArray &a = game->globalRAM[ptrval];
17996
17997 794 a.Resize(size);
17998 794 a.setValid(true);
17999 794 a.setObjectType(object_type);
18000
18001
2/2
✓ Branch 0 taken 1124622 times.
✓ Branch 1 taken 794 times.
1125416 for(dword j = 0; j < (dword)size; j++)
18002 1124622 a[j] = 0;
18003
18004 794 ptrval += NUM_ZSCRIPT_ARRAYS; //so each pointer has a unique value
18005 }
18006
18007 13698919 return ptrval * 10000;
18008 13698919 }
18009
18010 14191725 uint32_t allocatemem(int32_t size, bool local, ScriptType type, const uint32_t UID, script_object_type object_type)
18011 {
18012
2/2
✓ Branch 0 taken 13698919 times.
✓ Branch 1 taken 492806 times.
14191725 if (!ZScriptVersion::gc_arrays())
18013 13698919 return allocatemem_old(size, local, type, UID, object_type);
18014
18015
1/2
✓ Branch 0 taken 492806 times.
✗ Branch 1 not taken.
492806 if(size < 0)
18016 {
18017 Z_scripterrlog_force_trace("Array initialized to invalid size of %d\n", size);
18018 return 0;
18019 }
18020
18021 492806 auto* array = script_arrays.create();
18022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 492806 times.
492806 if (!array)
18023 return 0;
18024
18025 492806 ZScriptArray &a = array->arr;
18026 492806 a.Resize(size);
18027 492806 a.setValid(true);
18028 492806 a.setObjectType(object_type);
18029
18030
2/2
✓ Branch 0 taken 28713430 times.
✓ Branch 1 taken 492806 times.
29206236 for(dword j = 0; j < (dword)size; j++)
18031 28713430 a[j] = 0; //initialize array
18032
18033 492806 return array->id;
18034 14191725 }
18035
18036 14191725 void do_allocatemem(bool v, const bool local, ScriptType type, const uint32_t UID)
18037 {
18038 14191725 int32_t size = SH::get_arg(sarg2, v) / 10000;
18039
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14191725 times.
✓ Branch 2 taken 14191725 times.
✗ Branch 3 not taken.
14191725 assert(sarg3 >= 0 && sarg3 <= (int)script_object_type::last);
18040 14191725 uint32_t id = allocatemem(size, local, type, UID, (script_object_type)sarg3);
18041 14191725 set_register(sarg1, id);
18042 14191725 }
18043
18044 13664241 void do_deallocatemem()
18045 {
18046 13664241 const int32_t ptrval = get_register(sarg1) / 10000;
18047
18048 13664241 FFScript::deallocateArray(ptrval);
18049 13664241 }
18050
18051 ///----------------------------------------------------------------------------------------------------//
18052 //Mathematical
18053
18054 4838129 void do_add(const bool v)
18055 {
18056 4838129 int32_t temp = SH::get_arg(sarg2, v);
18057 4838129 int32_t temp2 = get_register(sarg1);
18058
18059 4838129 set_register(sarg1, temp2 + temp);
18060 4838129 }
18061
18062 215703 void do_sub(bool v, const bool inv = false)
18063 {
18064 215703 bool v2 = false;
18065
2/2
✓ Branch 0 taken 215697 times.
✓ Branch 1 taken 6 times.
215703 if(inv) zc_swap(v,v2);
18066
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 215697 times.
215703 auto destreg = (inv ? sarg2 : sarg1);
18067 215703 int32_t temp = SH::get_arg(sarg2, v);
18068 215703 int32_t temp2 = SH::get_arg(sarg1, v2);
18069 215703 set_register(destreg, temp2 - temp);
18070 215703 }
18071
18072 272205 void do_mult(const bool v)
18073 {
18074 272205 int64_t temp = SH::get_arg(sarg2, v);
18075 272205 int32_t temp2 = get_register(sarg1);
18076
18077 272205 set_register(sarg1, int32_t((temp * temp2) / 10000));
18078 272205 }
18079
18080 25681 void do_div(bool v, const bool inv = false)
18081 {
18082 25681 bool v2 = false;
18083
1/2
✓ Branch 0 taken 25681 times.
✗ Branch 1 not taken.
25681 if(inv) zc_swap(v,v2);
18084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25681 times.
25681 auto destreg = (inv ? sarg2 : sarg1);
18085 25681 int64_t temp = SH::get_arg(sarg2, v);
18086 25681 int64_t temp2 = SH::get_arg(sarg1, v2);
18087
18088
1/2
✓ Branch 0 taken 25681 times.
✗ Branch 1 not taken.
25681 if(temp == 0)
18089 {
18090 scripting_log_error_with_context("Attempted to divide by zero!");
18091 set_register(destreg, int32_t(sign(temp2) * MAX_SIGNED_32));
18092 }
18093 else
18094 {
18095 25681 set_register(destreg, int32_t((temp2 * 10000) / temp));
18096 }
18097 25681 }
18098
18099 42273 void do_mod(bool v, const bool inv = false)
18100 {
18101 42273 bool v2 = false;
18102
1/2
✓ Branch 0 taken 42273 times.
✗ Branch 1 not taken.
42273 if(inv) zc_swap(v,v2);
18103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42273 times.
42273 auto destreg = (inv ? sarg2 : sarg1);
18104 42273 int32_t temp = SH::get_arg(sarg2, v);
18105 42273 int32_t temp2 = SH::get_arg(sarg1, v2);
18106
18107
1/2
✓ Branch 0 taken 42273 times.
✗ Branch 1 not taken.
42273 if(temp == 0)
18108 {
18109 scripting_log_error_with_context("Attempted to modulo by zero!");
18110 temp = 1;
18111 }
18112
18113 42273 set_register(destreg, temp2 % temp);
18114 42273 }
18115
18116 16449574 void do_trig(const bool v, const byte type)
18117 {
18118 16449574 double rangle = (SH::get_arg(sarg2, v) / 10000.0) * PI / 180.0;
18119
18120
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9768934 times.
✓ Branch 2 taken 6680540 times.
✓ Branch 3 taken 100 times.
16449574 switch(type)
18121 {
18122 case 0:
18123 9768934 set_register(sarg1, int32_t(zc::math::Sin(rangle) * 10000.0));
18124 9768934 break;
18125
18126 case 1:
18127 6680540 set_register(sarg1, int32_t(zc::math::Cos(rangle) * 10000.0));
18128 6680540 break;
18129
18130 case 2:
18131 100 set_register(sarg1, int32_t(zc::math::Tan(rangle) * 10000.0));
18132 100 break;
18133 }
18134 16449574 }
18135
18136 3916 void do_degtorad()
18137 {
18138 3916 double rangle = (SH::get_arg(sarg2, false) / 10000.0) * (PI / 180.0);
18139 3916 rangle += rangle < 0?-0.00005:0.00005;
18140
18141 3916 set_register(sarg1, int32_t(rangle * 10000.0));
18142 3916 }
18143
18144 196070 void do_radtodeg()
18145 {
18146 196070 double rangle = (SH::get_arg(sarg2, false) / 10000.0) * (180.0 / PI);
18147
18148 196070 set_register(sarg1, int32_t(rangle * 10000.0));
18149 196070 }
18150
18151 14918 void do_asin(const bool v)
18152 {
18153 14918 double temp = double(SH::get_arg(sarg2, v)) / 10000.0;
18154
18155
2/4
✓ Branch 0 taken 14918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14918 times.
✗ Branch 3 not taken.
14918 if(temp >= -1 && temp <= 1)
18156 14918 set_register(sarg1, int32_t(asin(temp) * 10000.0));
18157 else
18158 {
18159 Z_scripterrlog("Script attempted to pass %f into ArcSin!\n",temp);
18160 set_register(sarg1, -10000);
18161 }
18162 14918 }
18163
18164 void do_acos(const bool v)
18165 {
18166 double temp = double(SH::get_arg(sarg2, v)) / 10000.0;
18167
18168 if(temp >= -1 && temp <= 1)
18169 set_register(sarg1, int32_t(acos(temp) * 10000.0));
18170 else
18171 {
18172 Z_scripterrlog("Script attempted to pass %f into ArcCos!\n",temp);
18173 set_register(sarg1, -10000);
18174 }
18175 }
18176
18177 5902190 void do_arctan()
18178 {
18179 5902190 double xpos = GET_D(rINDEX) / 10000.0;
18180 5902190 double ypos = GET_D(rINDEX2) / 10000.0;
18181
18182 5902190 set_register(sarg1, int32_t(atan2(ypos, xpos) * 10000.0));
18183 5902190 }
18184
18185 9100 void do_abs(const bool v)
18186 {
18187 9100 int32_t temp = SH::get_arg(sarg1, v);
18188 9100 set_register(sarg1, abs(temp));
18189 9100 }
18190
18191 969 void do_log10(const bool v)
18192 {
18193 969 double temp = double(SH::get_arg(sarg1, v)) / 10000.0;
18194
18195
1/2
✓ Branch 0 taken 969 times.
✗ Branch 1 not taken.
969 if(temp > 0)
18196 969 set_register(sarg1, int32_t(log10(temp) * 10000.0));
18197 else
18198 {
18199 Z_scripterrlog("Script tried to calculate log of %f\n", temp / 10000.0);
18200 set_register(sarg1, 0);
18201 }
18202 969 }
18203
18204 648 void do_naturallog(const bool v)
18205 {
18206 648 double temp = double(SH::get_arg(sarg1, v)) / 10000.0;
18207
18208
1/2
✓ Branch 0 taken 648 times.
✗ Branch 1 not taken.
648 if(temp > 0)
18209 648 set_register(sarg1, int32_t(log(temp) * 10000.0));
18210 else
18211 {
18212 Z_scripterrlog("Script tried to calculate ln of %f\n", temp / 10000.0);
18213 set_register(sarg1, 0);
18214 }
18215 648 }
18216
18217 2170 void do_min(const bool v)
18218 {
18219 2170 int32_t temp = SH::get_arg(sarg2, v);
18220 2170 int32_t temp2 = get_register(sarg1);
18221
2/2
✓ Branch 0 taken 1094 times.
✓ Branch 1 taken 1076 times.
2170 set_register(sarg1, zc_min(temp2, temp));
18222 2170 }
18223
18224 1332 void do_max(const bool v)
18225 {
18226 1332 int32_t temp = SH::get_arg(sarg2, v);
18227 1332 int32_t temp2 = get_register(sarg1);
18228
18229
2/2
✓ Branch 0 taken 172 times.
✓ Branch 1 taken 1160 times.
1332 set_register(sarg1, zc_max(temp2, temp));
18230 1332 }
18231 8306 void do_wrap_rad(const bool v)
18232 {
18233 8306 SET_D(rEXP1, wrap_zslong_rad(SH::get_arg(sarg1, v)));
18234 8306 }
18235 13037 void do_wrap_deg(const bool v)
18236 {
18237 13037 SET_D(rEXP1, wrap_zslong_deg(SH::get_arg(sarg1, v)));
18238 13037 }
18239
18240
18241 2918055 void do_rnd(const bool v)
18242 {
18243 2918055 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18244
18245
2/2
✓ Branch 0 taken 2892290 times.
✓ Branch 1 taken 25765 times.
2918055 if(temp > 0)
18246 2892290 set_register(sarg1, (zc_oldrand() % temp) * 10000);
18247
2/2
✓ Branch 0 taken 2755 times.
✓ Branch 1 taken 23010 times.
25765 else if(temp < 0)
18248 2755 set_register(sarg1, (zc_oldrand() % (-temp)) * -10000);
18249 else
18250 23010 set_register(sarg1, 0); // Just return 0. (Do not log an error)
18251 2918055 }
18252
18253 void do_srnd(const bool v)
18254 {
18255 uint32_t seed = SH::get_arg(sarg1, v); //Do not `/10000`- allow the decimal portion to be used! -V
18256 zc_game_srand(seed);
18257 }
18258
18259 void do_srndrnd()
18260 {
18261 //Randomize the seed to the current system time, + or - the product of 2 random numbers.
18262 int32_t seed = time(0) + ((zc_rand() * int64_t(zc_rand())) * (zc_rand(1) ? 1 : -1));
18263 set_register(sarg1, seed);
18264 zc_game_srand(seed);
18265 }
18266
18267 //Returns the system Real-Time-Clock value.
18268 15 void FFScript::getRTC()
18269 {
18270 //int32_t type = get_register(sarg1) / 10000;
18271 //int32_t time = getTime(type);
18272 15 set_register(sarg1, getTime((get_register(sarg1) / 10000)) * 10000);
18273 15 }
18274
18275
18276 void do_factorial(const bool v)
18277 {
18278 int32_t temp;
18279
18280 if(v)
18281 return; //must factorial a register, not a value (why is this exactly? ~Joe123)
18282 else
18283 {
18284 temp = get_register(sarg1) / 10000;
18285
18286 if(temp < 2)
18287 {
18288 set_register(sarg1, temp >= 0 ? 10000 : 0);
18289 return;
18290 }
18291 }
18292
18293 int32_t temp2 = 1;
18294
18295 for(int32_t temp3 = temp; temp > 1; temp--)
18296 temp2 *= temp3;
18297
18298 set_register(sarg1, temp2 * 10000);
18299 }
18300
18301 6556 void do_power(bool v, const bool inv = false)
18302 {
18303 6556 bool v2 = false;
18304
1/2
✓ Branch 0 taken 6556 times.
✗ Branch 1 not taken.
6556 if(inv) zc_swap(v,v2);
18305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6556 times.
6556 auto destreg = (inv ? sarg2 : sarg1);
18306 6556 double temp = double(SH::get_arg(sarg2, v)) / 10000.0;
18307 6556 double temp2 = double(SH::get_arg(sarg1, v2)) / 10000.0;
18308
18309
3/4
✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 5263 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1293 times.
6556 if(temp == 0 && temp2 == 0)
18310 {
18311 set_register(destreg, 10000);
18312 return;
18313 }
18314
18315 6556 set_register(destreg, int32_t(pow(temp2, temp) * 10000.0));
18316 6556 }
18317
18318 void do_lpower(bool v, const bool inv = false)
18319 {
18320 bool v2 = false;
18321 if(inv) zc_swap(v,v2);
18322 auto destreg = (inv ? sarg2 : sarg1);
18323 int32_t temp = SH::get_arg(sarg2, v);
18324 int32_t temp2 = SH::get_arg(sarg1, v2);
18325
18326 if(temp == 0 && temp2 == 0)
18327 {
18328 set_register(destreg, 1);
18329 return;
18330 }
18331
18332 set_register(destreg, int32_t(pow(temp2, temp)));
18333 }
18334
18335 //could use recursion or something to avoid truncation.
18336 void do_ipower(const bool v)
18337 {
18338 double sarg2val = double(SH::get_arg(sarg2, v));
18339 if ( sarg2val == 0 )
18340 {
18341 Z_scripterrlog("Division by 0 Err: InvPower() exponent divisor cannot be 0!!\n");
18342 set_register(sarg1, 1);
18343 return;
18344 }
18345 double temp = 10000.0 / sarg2val;
18346 double temp2 = double(get_register(sarg1)) / 10000.0;
18347
18348 if(temp == 0 && temp2 == 0)
18349 {
18350 set_register(sarg1, 1);
18351 return;
18352 }
18353
18354 set_register(sarg1, int32_t(pow(temp2, temp) * 10000.0));
18355 }
18356
18357 10089782 void do_sqroot(const bool v)
18358 {
18359 10089782 double temp = double(SH::get_arg(sarg2, v)) / 10000.0;
18360
18361
2/2
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 10089360 times.
10089782 if(temp < 0)
18362 {
18363 422 Z_scripterrlog("Script attempted to calculate square root of %f!\n", temp);
18364 422 set_register(sarg1, -10000);
18365 422 return;
18366 }
18367
18368 10089360 set_register(sarg1, int32_t(sqrt(temp) * 10000.0));
18369 10089782 }
18370
18371 ///----------------------------------------------------------------------------------------------------//
18372 //Bitwise
18373
18374 165132 void do_and(const bool v)
18375 {
18376 165132 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18377 165132 int32_t temp2 = get_register(sarg1) / 10000;
18378 165132 set_register(sarg1, (temp2 & temp) * 10000);
18379 165132 }
18380
18381 362787 void do_and32(const bool v)
18382 {
18383 362787 int32_t temp = SH::get_arg(sarg2, v);
18384 362787 int32_t temp2 = get_register(sarg1);
18385 362787 set_register(sarg1, (temp2 & temp));
18386 362787 }
18387
18388 4411 void do_or(const bool v)
18389 {
18390 4411 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18391 4411 int32_t temp2 = get_register(sarg1) / 10000;
18392 4411 set_register(sarg1, (temp2 | temp) * 10000);
18393 4411 }
18394
18395 void do_or32(const bool v)
18396 {
18397 int32_t temp = SH::get_arg(sarg2, v);
18398 int32_t temp2 = get_register(sarg1);
18399 set_register(sarg1, (temp2 | temp));
18400 }
18401
18402 927917 void do_xor(const bool v)
18403 {
18404 927917 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18405 927917 int32_t temp2 = get_register(sarg1) / 10000;
18406 927917 set_register(sarg1, (temp2 ^ temp) * 10000);
18407 927917 }
18408
18409 void do_xor32(const bool v)
18410 {
18411 int32_t temp = SH::get_arg(sarg2, v);
18412 int32_t temp2 = get_register(sarg1);
18413 set_register(sarg1, (temp2 ^ temp));
18414 }
18415
18416 void do_nand(const bool v)
18417 {
18418 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18419 int32_t temp2 = get_register(sarg1) / 10000;
18420 set_register(sarg1, (~(temp2 & temp)) * 10000);
18421 }
18422
18423 void do_nor(const bool v)
18424 {
18425 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18426 int32_t temp2 = get_register(sarg1) / 10000;
18427 set_register(sarg1, (~(temp2 | temp)) * 10000);
18428 }
18429
18430 void do_xnor(const bool v)
18431 {
18432 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18433 int32_t temp2 = get_register(sarg1) / 10000;
18434 set_register(sarg1, (~(temp2 ^ temp)) * 10000);
18435 }
18436
18437 void do_not(const bool v)
18438 {
18439 int32_t temp = SH::get_arg(sarg2, v);
18440 set_register(sarg1, !temp);
18441 }
18442
18443 3719887 void do_bitwisenot(const bool v)
18444 {
18445 3719887 int32_t temp = SH::get_arg(sarg1, v) / 10000;
18446 3719887 set_register(sarg1, (~temp) * 10000);
18447 3719887 }
18448
18449 4 void do_bitwisenot32(const bool v)
18450 {
18451 4 int32_t temp = SH::get_arg(sarg1, v);
18452 4 set_register(sarg1, (~temp));
18453 4 }
18454
18455 85034301 void do_lshift(const bool v)
18456 {
18457 85034301 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18458 85034301 int32_t temp2 = get_register(sarg1) / 10000;
18459 85034301 set_register(sarg1, (temp2 << temp) * 10000);
18460 85034301 }
18461
18462 317888 void do_lshift32(const bool v)
18463 {
18464 317888 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18465 317888 int32_t temp2 = get_register(sarg1);
18466 317888 set_register(sarg1, (temp2 << temp));
18467 317888 }
18468
18469 31991089 void do_rshift(const bool v)
18470 {
18471 31991089 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18472 31991089 int32_t temp2 = get_register(sarg1) / 10000;
18473 31991089 set_register(sarg1, (temp2 >> temp) * 10000);
18474 31991089 }
18475
18476 34296 void do_rshift32(const bool v)
18477 {
18478 34296 int32_t temp = SH::get_arg(sarg2, v) / 10000;
18479 34296 int32_t temp2 = get_register(sarg1);
18480 34296 set_register(sarg1, (temp2 >> temp));
18481 34296 }
18482
18483 ///----------------------------------------------------------------------------------------------------//
18484 //Casting
18485
18486 void do_boolcast(const bool isFloat)
18487 {
18488 set_register(sarg1, (get_register(sarg1) ? (isFloat ? 1 : 10000) : 0));
18489 }
18490
18491 ///----------------------------------------------------------------------------------------------------//
18492 //Text ptr functions
18493 32282 void do_fontheight()
18494 {
18495 32282 int32_t font = get_register(sarg1)/10000;
18496 32282 SET_D(rEXP1, text_height(get_zc_font(font))*10000);
18497 32282 }
18498
18499 18404 void do_strwidth()
18500 {
18501 18404 int32_t strptr = get_register(sarg1);
18502 18404 int32_t font = get_register(sarg2)/10000;
18503 18404 string the_string;
18504
1/2
✓ Branch 0 taken 18404 times.
✗ Branch 1 not taken.
18404 ArrayH::getString(strptr, the_string, 512);
18505
2/4
✓ Branch 0 taken 18404 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18404 times.
✗ Branch 3 not taken.
18404 SET_D(rEXP1, text_length(get_zc_font(font), the_string.c_str())*10000);
18506 18404 }
18507
18508 250385 void do_charwidth()
18509 {
18510 250385 char chr = get_register(sarg1)/10000;
18511 250385 int32_t font = get_register(sarg2)/10000;
18512 250385 char *cstr = new char[2];
18513 250385 cstr[0] = chr;
18514 250385 cstr[1] = '\0';
18515 250385 SET_D(rEXP1, text_length(get_zc_font(font), cstr)*10000);
18516
1/2
✓ Branch 0 taken 250385 times.
✗ Branch 1 not taken.
250385 delete[] cstr;
18517 250385 }
18518
18519 int32_t do_msgwidth(int32_t ID)
18520 {
18521 if(BC::checkMessage(ID) != SH::_NoError)
18522 {
18523 return -1;
18524 }
18525
18526 int32_t v = text_length(get_zc_font(MsgStrings[ID].font),
18527 MsgStrings[ID].s.substr(0,MsgStrings[ID].s.find_last_not_of(' ')+1).c_str());
18528 return v;
18529 }
18530
18531 int32_t do_msgheight(int32_t ID)
18532 {
18533 if(BC::checkMessage(ID) != SH::_NoError)
18534 {
18535 return -1;
18536 }
18537 return text_height(get_zc_font(MsgStrings[ID].font));
18538 }
18539
18540 ///----------------------------------------------------------------------------------------------------//
18541 //Gameplay functions
18542
18543 123 void do_warp(bool v)
18544 {
18545 123 int32_t dmapid = SH::get_arg(sarg1, v) / 10000;
18546 123 int32_t screen = SH::get_arg(sarg2, v) / 10000;
18547
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
123 if ( ((unsigned)dmapid) >= MAXDMAPS )
18548 {
18549 Z_scripterrlog("Invalid DMap ID (%d) passed to Warp(). Aborting.\n", dmapid);
18550 return;
18551 }
18552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
123 if ( ((unsigned)screen) >= MAPSCRS )
18553 {
18554 Z_scripterrlog("Invalid Screen Index (%d) passed to Warp(). Aborting.\n", screen);
18555 return;
18556 }
18557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
123 if ( map_screen_index(DMaps[dmapid].map, screen + DMaps[dmapid].xoff) >= (int32_t)TheMaps.size() )
18558 {
18559 Z_scripterrlog("Invalid destination passed to Warp(). Aborting.\n");
18560 return;
18561 }
18562 123 hero_scr->sidewarpdmap[0] = dmapid;
18563 123 hero_scr->sidewarpscr[0] = screen;
18564 123 hero_scr->sidewarptype[0] = wtIWARP;
18565
1/2
✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
123 if(!get_qr(qr_OLD_HERO_WARP_RETSQUARE))
18566 {
18567 hero_scr->warpreturnc &= ~(3 << 8);
18568 set_bit(&hero_scr->sidewarpoverlayflags,0,0);
18569 }
18570 123 Hero.ffwarp = true;
18571 123 }
18572
18573 127 void do_pitwarp(bool v)
18574 {
18575 127 int32_t dmapid = SH::get_arg(sarg1, v) / 10000;
18576 127 int32_t screen = SH::get_arg(sarg2, v) / 10000;
18577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if ( ((unsigned)dmapid) >= MAXDMAPS )
18578 {
18579 Z_scripterrlog("Invalid DMap ID (%d) passed to PitWarp(). Aborting.\n", dmapid);
18580 return;
18581 }
18582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if ( ((unsigned)screen) >= MAPSCRS )
18583 {
18584 Z_scripterrlog("Invalid Screen Index (%d) passed to PitWarp(). Aborting.\n", screen);
18585 return;
18586 }
18587 //Extra sanity guard.
18588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if ( map_screen_index(DMaps[dmapid].map, screen + DMaps[dmapid].xoff) >= (int32_t)TheMaps.size() )
18589 {
18590 Z_scripterrlog("Invalid destination passed to Warp(). Aborting.\n");
18591 return;
18592 }
18593 127 hero_scr->sidewarpdmap[0] = dmapid;
18594 127 hero_scr->sidewarpscr[0] = screen;
18595 127 hero_scr->sidewarptype[0] = wtIWARP;
18596
1/2
✓ Branch 0 taken 127 times.
✗ Branch 1 not taken.
127 if(!get_qr(qr_OLD_HERO_WARP_RETSQUARE))
18597 {
18598 hero_scr->warpreturnc &= ~(3 << 8);
18599 set_bit(&hero_scr->sidewarpoverlayflags,0,0);
18600 }
18601 127 Hero.ffwarp = true;
18602 127 Hero.ffpit = true;
18603 127 }
18604
18605
18606
18607 void do_showsavescreen()
18608 {
18609 bool didsaved = save_game(false, 0);
18610 set_register(sarg1, didsaved ? 10000 : 0);
18611 }
18612
18613 11096 void do_selectweapon(bool v, int32_t btn)
18614 {
18615
2/4
✓ Branch 0 taken 5436 times.
✓ Branch 1 taken 5660 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11096 switch(btn)
18616 {
18617 case 1:
18618
1/2
✓ Branch 0 taken 5660 times.
✗ Branch 1 not taken.
5660 if(!get_qr(qr_SELECTAWPN))
18619 return;
18620 5660 break;
18621 case 2:
18622 if(!get_qr(qr_SET_XBUTTON_ITEMS))
18623 return;
18624 break;
18625 case 3:
18626 if(!get_qr(qr_SET_YBUTTON_ITEMS))
18627 return;
18628 break;
18629 }
18630
18631 11096 byte dir=(byte)(SH::get_arg(sarg1, v)/10000);
18632
18633 // Selection directions don't match the normal ones...
18634
2/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
✓ Branch 4 taken 11016 times.
11096 switch(dir)
18635 {
18636 case 0:
18637 dir=SEL_UP;
18638 break;
18639
18640 case 1:
18641 dir=SEL_DOWN;
18642 break;
18643
18644 case 2:
18645 80 dir=SEL_LEFT;
18646 80 break;
18647
18648 case 3:
18649 11016 dir=SEL_RIGHT;
18650 11016 break;
18651
18652 default:
18653 return;
18654 }
18655
18656
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5436 times.
✓ Branch 2 taken 5660 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
11096 switch(btn)
18657 {
18658 case 0:
18659 5436 selectNextBWpn(dir);
18660 5436 break;
18661 case 1:
18662 5660 selectNextAWpn(dir);
18663 5660 break;
18664 case 2:
18665 selectNextXWpn(dir);
18666 break;
18667 case 3:
18668 selectNextYWpn(dir);
18669 break;
18670 }
18671 11096 }
18672
18673 ///----------------------------------------------------------------------------------------------------//
18674 //Screen Information
18675
18676 25461489 void do_issolid()
18677 {
18678 25461489 int32_t x = int32_t(GET_D(rINDEX) / 10000);
18679 25461489 int32_t y = int32_t(GET_D(rINDEX2) / 10000);
18680
18681 25461489 set_register(sarg1, (_walkflag(x, y, 1) ? 10000 : 0));
18682 25461489 }
18683
18684 void do_mapdataissolid()
18685 {
18686 int32_t x = int32_t(GET_D(rINDEX) / 10000);
18687 int32_t y = int32_t(GET_D(rINDEX2) / 10000);
18688
18689 auto result = decode_mapdata_ref(GET_REF(mapdataref));
18690 if (!result.scr)
18691 {
18692 scripting_log_error_with_context("mapdata pointer is either invalid or uninitialised");
18693 set_register(sarg1,10000);
18694 }
18695 else
18696 {
18697 if (result.type == mapdata_type::CanonicalScreen)
18698 {
18699 set_register(sarg1, (_walkflag(x, y, 1, result.scr) ? 10000 : 0));
18700 return;
18701 }
18702
18703 if (result.type == mapdata_type::TemporaryCurrentRegion && result.layer == 0)
18704 {
18705 set_register(sarg1, (_walkflag(x, y, 1)) ? 10000 : 0);
18706 }
18707 else if (result.type == mapdata_type::TemporaryScrollingRegion && result.layer == 0)
18708 {
18709 mapscr* s0 = GetScrollingMapscr(0, x, y);
18710 mapscr* s1 = GetScrollingMapscr(1, x, y);
18711 mapscr* s2 = GetScrollingMapscr(2, x, y);
18712 if (!s1->valid) s1 = s0;
18713 if (!s2->valid) s2 = s0;
18714 bool result = _walkflag_new(s0, s1, s2, x, y, 0_zf, true);
18715 set_register(sarg1, result ? 10000 : 0);
18716 }
18717 else
18718 {
18719 set_register(sarg1, (_walkflag(x, y, 1, result.scr) ? 10000 : 0));
18720 }
18721 }
18722 }
18723
18724 void do_mapdataissolid_layer()
18725 {
18726 int32_t x = int32_t(GET_D(rINDEX) / 10000);
18727 int32_t y = int32_t(GET_D(rINDEX2) / 10000);
18728 int32_t layer = int32_t(GET_D(rEXP1) / 10000);
18729
18730 auto result = decode_mapdata_ref(GET_REF(mapdataref));
18731 if (!result.scr)
18732 {
18733 scripting_log_error_with_context("mapdata pointer is either invalid or uninitialised");
18734 set_register(sarg1,10000);
18735 }
18736 else
18737 {
18738 if(BC::checkBounds(layer, 0, 6) != SH::_NoError)
18739 {
18740 set_register(sarg1,10000);
18741 }
18742 else
18743 {
18744 if (result.type == mapdata_type::TemporaryCurrentRegion && result.layer == 0)
18745 {
18746 set_register(sarg1, (_walkflag_layer(x, y, 1, result.scr)) ? 10000 : 0);
18747 }
18748 else if (result.type == mapdata_type::TemporaryScrollingRegion && result.layer == 0)
18749 {
18750 set_register(sarg1, (_walkflag_layer_scrolling(x, y, 1, result.scr)) ? 10000 : 0);
18751 }
18752 else
18753 {
18754 mapscr* m = result.scr;
18755
18756 if(layer > 0)
18757 {
18758 if(m->layermap[layer] == 0)
18759 {
18760 set_register(sarg1,10000);
18761 return;
18762 }
18763
18764 m = &TheMaps[(m->layermap[layer]*MAPSCRS + m->layerscreen[layer])];
18765 }
18766
18767 set_register(sarg1, (_walkflag_layer(x, y, 1, m) ? 10000 : 0));
18768 }
18769 }
18770 }
18771 }
18772
18773 void do_issolid_layer()
18774 {
18775 int32_t x = int32_t(GET_D(rINDEX) / 10000);
18776 int32_t y = int32_t(GET_D(rINDEX2) / 10000);
18777 int32_t layer = int32_t(GET_D(rEXP1) / 10000);
18778
18779 if(BC::checkBounds(layer, 0, 6) != SH::_NoError)
18780 {
18781 set_register(sarg1,10000);
18782 }
18783 else
18784 {
18785 set_register(sarg1, (_walkflag_layer(x, y, layer - 1, 1)) ? 10000 : 0);
18786 }
18787 }
18788
18789 257 void do_setsidewarp()
18790 {
18791 257 int32_t warp = SH::read_stack(ri->sp + 3) / 10000;
18792 257 int32_t scrn = SH::read_stack(ri->sp + 2) / 10000;
18793 257 int32_t dmap = SH::read_stack(ri->sp + 1) / 10000;
18794 257 int32_t type = SH::read_stack(ri->sp + 0) / 10000;
18795
18796 257 current_zasm_extra_context = "warp";
18797
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
257 if (BC::checkBounds(warp, -1, 3) != SH::_NoError)
18798 return;
18799
18800 257 current_zasm_extra_context = "screen";
18801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
257 if (BC::checkBounds(scrn, -1, 0x87) != SH::_NoError)
18802 return;
18803
18804 257 current_zasm_extra_context = "dmap";
18805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 257 times.
257 if (BC::checkBounds(dmap, -1, MAXDMAPS - 1) != SH::_NoError)
18806 return;
18807
18808 257 current_zasm_extra_context = "type";
18809
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if (BC::checkBounds(type, -1, wtMAX - 1) != SH::_NoError)
18810 return;
18811
18812 257 current_zasm_extra_context = "";
18813
18814 257 mapscr* scr = get_scr(GET_REF(screenref));
18815
18816
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if(scrn > -1)
18817 257 scr->sidewarpscr[warp] = scrn;
18818
18819
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if(dmap > -1)
18820 257 scr->sidewarpdmap[warp] = dmap;
18821
18822
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if(type > -1)
18823 257 scr->sidewarptype[warp] = type;
18824 257 }
18825
18826 5 void do_settilewarp()
18827 {
18828 5 int32_t warp = SH::read_stack(ri->sp + 3) / 10000;
18829 5 int32_t scrn = SH::read_stack(ri->sp + 2) / 10000;
18830 5 int32_t dmap = SH::read_stack(ri->sp + 1) / 10000;
18831 5 int32_t type = SH::read_stack(ri->sp + 0) / 10000;
18832
18833 5 current_zasm_extra_context = "warp";
18834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (BC::checkBounds(warp, -1, 3) != SH::_NoError)
18835 return;
18836
18837 5 current_zasm_extra_context = "screen";
18838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (BC::checkBounds(scrn, -1, 0x87) != SH::_NoError)
18839 return;
18840
18841 5 current_zasm_extra_context = "dmap";
18842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (BC::checkBounds(dmap, -1, MAXDMAPS - 1) != SH::_NoError)
18843 return;
18844
18845 5 current_zasm_extra_context = "type";
18846
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (BC::checkBounds(type, -1, wtMAX - 1) != SH::_NoError)
18847 return;
18848
18849 5 current_zasm_extra_context = "";
18850
18851 5 mapscr* scr = get_scr(GET_REF(screenref));
18852
18853
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(scrn > -1)
18854 5 scr->tilewarpscr[warp] = scrn;
18855
18856
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(dmap > -1)
18857 5 scr->tilewarpdmap[warp] = dmap;
18858
18859
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(type > -1)
18860 5 scr->tilewarptype[warp] = type;
18861 5 }
18862
18863 364895 void do_getsidewarpdmap(const bool v)
18864 {
18865 364895 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18866
18867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364895 times.
364895 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18868 {
18869 set_register(sarg1, -10000);
18870 return;
18871 }
18872
18873 364895 set_register(sarg1, get_scr(GET_REF(screenref))->sidewarpdmap[warp]*10000);
18874 364895 }
18875
18876 3 void do_getsidewarpscr(const bool v)
18877 {
18878 3 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18879
18880
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18881 {
18882 set_register(sarg1, -10000);
18883 return;
18884 }
18885
18886 3 set_register(sarg1, get_scr(GET_REF(screenref))->sidewarpscr[warp]*10000);
18887 3 }
18888
18889 void do_getsidewarptype(const bool v)
18890 {
18891 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18892
18893 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18894 {
18895 set_register(sarg1, -10000);
18896 return;
18897 }
18898
18899 set_register(sarg1, get_scr(GET_REF(screenref))->sidewarptype[warp]*10000);
18900 }
18901
18902 364942 void do_gettilewarpdmap(const bool v)
18903 {
18904 364942 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18905
18906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364942 times.
364942 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18907 {
18908 set_register(sarg1, -10000);
18909 return;
18910 }
18911
18912 364942 set_register(sarg1, get_scr(GET_REF(screenref))->tilewarpdmap[warp]*10000);
18913 364942 }
18914
18915 50 void do_gettilewarpscr(const bool v)
18916 {
18917 50 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18918
18919
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18920 {
18921 set_register(sarg1, -10000);
18922 return;
18923 }
18924
18925 50 set_register(sarg1, get_scr(GET_REF(screenref))->tilewarpscr[warp]*10000);
18926 50 }
18927
18928 3 void do_gettilewarptype(const bool v)
18929 {
18930 3 int32_t warp = SH::get_arg(sarg1, v) / 10000;
18931
18932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(BC::checkBounds(warp, -1, 3) != SH::_NoError)
18933 {
18934 set_register(sarg1, -10000);
18935 return;
18936 }
18937
18938 3 set_register(sarg1, get_scr(GET_REF(screenref))->tilewarptype[warp]*10000);
18939 3 }
18940
18941 13670631 void do_layerscreen()
18942 {
18943 13670631 int32_t layer = (get_register(sarg2) / 10000) - 1;
18944
18945
3/4
✓ Branch 0 taken 13670631 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11796293 times.
✓ Branch 3 taken 1874338 times.
13670631 if(BC::checkBounds(layer, 0, 5) != SH::_NoError || get_scr(GET_REF(screenref))->layermap[layer] == 0)
18946 1874338 set_register(sarg1, -10000);
18947 else
18948 11796293 set_register(sarg1, get_scr(GET_REF(screenref))->layerscreen[layer] * 10000);
18949 13670631 }
18950
18951 18282859 void do_layermap()
18952 {
18953 18282859 int32_t layer = (get_register(sarg2) / 10000) - 1;
18954
18955
3/4
✓ Branch 0 taken 18282859 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15796322 times.
✓ Branch 3 taken 2486537 times.
18282859 if(BC::checkBounds(layer, 0, 5) != SH::_NoError || get_scr(GET_REF(screenref))->layermap[layer] == 0)
18956 2486537 set_register(sarg1, -10000);
18957 else
18958 15796322 set_register(sarg1, get_scr(GET_REF(screenref))->layermap[layer] * 10000);
18959 18282859 }
18960
18961
18962
18963 500 void do_triggersecrets(int screen)
18964 {
18965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 500 times.
500 if (!is_in_current_region(screen))
18966 {
18967 scripting_log_error_with_context("Must be given a screen in the current region. got: {}", screen);
18968 return;
18969 }
18970
18971 500 trigger_secrets_for_screen(TriggerSource::Script, screen, false);
18972 500 }
18973
18974 void FFScript::do_graphics_getpixel()
18975 {
18976 int32_t ref = (GET_D(rEXP1));
18977 int32_t xpos = GET_D(rINDEX2) / 10000;
18978 int32_t ypos = (GET_D(rINDEX) / 10000);
18979
18980 BITMAP *bitty = FFCore.GetScriptBitmap(ref, screen);
18981
18982 const bool brokenOffset= ( (get_er(er_BITMAPOFFSET)!=0) || (get_qr(qr_BITMAPOFFSETFIX)!=0) );
18983 if(!brokenOffset && (ref-10) == -1 )
18984 {
18985 ypos += 56; //should this be -56?
18986 }
18987 else
18988 {
18989 ypos += 0;
18990 }
18991
18992 if(!bitty)
18993 {
18994 bitty = scrollbuf;
18995 }
18996
18997 // Note: getpixel will return -1 when out of bounds.
18998 if (!is_inside_bitmap(bitty, xpos, ypos, false))
18999 Z_scripterrlog("Invalid coordinate for getpixel. Bitmap: %dx%d, pixel: %dx%d\n", bitty->w, bitty->h, xpos, ypos);
19000
19001 int32_t ret = getpixel(bitty, xpos, ypos); //This is a palette index value.
19002
19003 if(!get_qr(qr_BROKEN_GETPIXEL_VALUE))
19004 ret *= 10000;
19005 set_register(sarg1, ret);
19006 }
19007
19008
19009
19010
19011 ///----------------------------------------------------------------------------------------------------//
19012 //Pointer handling
19013
19014 601509 bool is_valid_array(int32_t ptr)
19015 {
19016
2/2
✓ Branch 0 taken 601494 times.
✓ Branch 1 taken 15 times.
601509 if(!ptr) return false;
19017
19018
2/2
✓ Branch 0 taken 600928 times.
✓ Branch 1 taken 566 times.
601494 if (ZScriptVersion::gc_arrays())
19019 {
19020
1/2
✓ Branch 0 taken 600928 times.
✗ Branch 1 not taken.
600928 if (auto array = checkArray(ptr, true))
19021 600928 return !array->internal_expired;
19022
19023 return false;
19024 }
19025
19026 566 ptr /= 10000;
19027
19028
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 1 times.
566 if(ptr < 0) //An object array?
19029 {
19030 1 int32_t objptr = -ptr;
19031 1 auto it = objectRAM.find(objptr);
19032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(it == objectRAM.end())
19033 return false;
19034 1 return true;
19035 }
19036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 565 times.
565 else if(ptr >= NUM_ZSCRIPT_ARRAYS) //check global
19037 {
19038 dword gptr = ptr - NUM_ZSCRIPT_ARRAYS;
19039
19040 if(gptr > game->globalRAM.size())
19041 return false;
19042 else return game->globalRAM[gptr].Valid();
19043 }
19044 else
19045 {
19046 565 return localRAM[ptr].Valid();
19047 }
19048 601509 }
19049
19050 601509 void do_isvalidarray()
19051 {
19052 601509 int32_t ptr = get_register(sarg1);
19053
19054 601509 set_register(sarg1,is_valid_array(ptr) ? 10000 : 0);
19055 601509 }
19056
19057 31517 void do_isvaliditem()
19058 {
19059 31517 int32_t IID = get_register(sarg1);
19060 //int32_t ct = items.Count();
19061
19062 //for ( int32_t j = items.Count()-1; j >= 0; --j )
19063
2/2
✓ Branch 0 taken 55637 times.
✓ Branch 1 taken 213 times.
55850 for(int32_t j = 0; j < items.Count(); j++)
19064 //for(int32_t j = 0; j < ct; j++)
19065
2/2
✓ Branch 0 taken 31304 times.
✓ Branch 1 taken 24333 times.
55637 if(items.spr(j)->getUID() == IID)
19066 {
19067 31304 set_register(sarg1, 10000);
19068 31304 return;
19069 }
19070
19071 213 set_register(sarg1, 0);
19072 31517 }
19073
19074 11796078 void do_isvalidnpc()
19075 {
19076 11796078 int32_t UID = get_register(sarg1);
19077 //for ( int32_t j = guys.Count()-1; j >= 0; --j )
19078 //int32_t ct = guys.Count();
19079
19080
2/2
✓ Branch 0 taken 34259778 times.
✓ Branch 1 taken 112147 times.
34371925 for(int32_t j = 0; j < guys.Count(); j++)
19081 //for(int32_t j = 0; j < ct; j++)
19082
2/2
✓ Branch 0 taken 11683931 times.
✓ Branch 1 taken 22575847 times.
34259778 if(guys.spr(j)->getUID() == UID)
19083 {
19084 11683931 set_register(sarg1, 10000);
19085 11683931 return;
19086 }
19087
19088 112147 set_register(sarg1, 0);
19089 11796078 }
19090
19091 1279180 void do_isvalidlwpn()
19092 {
19093 1279180 int32_t WID = get_register(sarg1);
19094 //int32_t ct = Lwpns.Count();
19095
19096 //for ( int32_t j = Lwpns.Count()-1; j >= 0; --j )
19097
2/2
✓ Branch 0 taken 8771625 times.
✓ Branch 1 taken 590880 times.
9362505 for(int32_t j = 0; j < Lwpns.Count(); j++)
19098 //for(int32_t j = 0; j < ct; j++)
19099
2/2
✓ Branch 0 taken 8083325 times.
✓ Branch 1 taken 688300 times.
8771625 if(Lwpns.spr(j)->getUID() == WID)
19100 {
19101 688300 set_register(sarg1, 10000);
19102 688300 return;
19103 }
19104
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 590880 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
590880 if(Hero.lift_wpn && Hero.lift_wpn->getUID() == WID)
19105 {
19106 set_register(sarg1, 10000);
19107 return;
19108 }
19109 590880 set_register(sarg1, 0);
19110 1279180 }
19111
19112 176099 void do_isvalidewpn()
19113 {
19114 176099 int32_t WID = get_register(sarg1);
19115
19116
2/2
✓ Branch 0 taken 1360619 times.
✓ Branch 1 taken 24089 times.
1384708 for(int32_t j = 0; j < Ewpns.Count(); j++)
19117
2/2
✓ Branch 0 taken 1208609 times.
✓ Branch 1 taken 152010 times.
1360619 if(Ewpns.spr(j)->getUID() == WID)
19118 {
19119 152010 set_register(sarg1, 10000);
19120 152010 return;
19121 }
19122 // unsure how an ewpn would be lifted, but, checking just to be safe
19123
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 24089 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
24089 if(Hero.lift_wpn && Hero.lift_wpn->getUID() == WID)
19124 {
19125 set_register(sarg1, 10000);
19126 return;
19127 }
19128 24089 set_register(sarg1, 0);
19129 176099 }
19130
19131 void do_lwpnmakeangular()
19132 {
19133 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
19134 {
19135 auto w = LwpnH::getWeapon();
19136 if (!w->angular)
19137 {
19138 double vx;
19139 double vy;
19140 switch(NORMAL_DIR(w->dir))
19141 {
19142 case l_up:
19143 case l_down:
19144 case left:
19145 vx = -1.0*w->step;
19146 break;
19147 case r_down:
19148 case r_up:
19149 case right:
19150 vx = w->step;
19151 break;
19152
19153 default:
19154 vx = 0;
19155 break;
19156 }
19157 switch(NORMAL_DIR(w->dir))
19158 {
19159 case l_up:
19160 case r_up:
19161 case up:
19162 vy = -1.0*w->step;
19163 break;
19164 case l_down:
19165 case r_down:
19166 case down:
19167 vy = w->step;
19168 break;
19169
19170 default:
19171 vy = 0;
19172 break;
19173 }
19174 w->angular = true;
19175 w->angle=atan2(vy, vx);
19176 w->step=FFCore.Distance(0, 0, vx, vy)/10000.0;
19177 w->doAutoRotate();
19178 }
19179 }
19180 }
19181
19182 void do_lwpnmakedirectional()
19183 {
19184 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
19185 {
19186 if (LwpnH::getWeapon()->angular)
19187 {
19188 LwpnH::getWeapon()->dir = NORMAL_DIR(AngleToDir(WrapAngle(LwpnH::getWeapon()->angle)));
19189 LwpnH::getWeapon()->angular = false;
19190 LwpnH::getWeapon()->doAutoRotate(true);
19191 }
19192 }
19193 }
19194
19195 void do_ewpnmakeangular()
19196 {
19197 if(EwpnH::loadWeapon(GET_REF(ewpnref)) == SH::_NoError)
19198 {
19199 auto w = EwpnH::getWeapon();
19200 if (!w->angular)
19201 {
19202 double vx;
19203 double vy;
19204 switch(NORMAL_DIR(w->dir))
19205 {
19206 case l_up:
19207 case l_down:
19208 case left:
19209 vx = -1.0*w->step;
19210 break;
19211 case r_down:
19212 case r_up:
19213 case right:
19214 vx = w->step;
19215 break;
19216
19217 default:
19218 vx = 0;
19219 break;
19220 }
19221 switch(NORMAL_DIR(w->dir))
19222 {
19223 case l_up:
19224 case r_up:
19225 case up:
19226 vy = -1.0*w->step;
19227 break;
19228 case l_down:
19229 case r_down:
19230 case down:
19231 vy = w->step;
19232 break;
19233
19234 default:
19235 vy = 0;
19236 break;
19237 }
19238 w->angular = true;
19239 w->angle=atan2(vy, vx);
19240 w->step=FFCore.Distance(0, 0, vx, vy)/10000.0;
19241 w->doAutoRotate();
19242 }
19243 }
19244 }
19245
19246 void do_ewpnmakedirectional()
19247 {
19248 if(EwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
19249 {
19250 if (EwpnH::getWeapon()->angular)
19251 {
19252 EwpnH::getWeapon()->dir = NORMAL_DIR(AngleToDir(WrapAngle(EwpnH::getWeapon()->angle)));
19253 EwpnH::getWeapon()->angular = false;
19254 EwpnH::getWeapon()->doAutoRotate(true);
19255 }
19256 }
19257 }
19258
19259 20064 void do_lwpnusesprite(const bool v)
19260 {
19261 20064 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19262
19263
1/2
✓ Branch 0 taken 20064 times.
✗ Branch 1 not taken.
20064 if(BC::checkWeaponMiscSprite(ID) != SH::_NoError)
19264 return;
19265
19266
1/2
✓ Branch 0 taken 20064 times.
✗ Branch 1 not taken.
20064 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
19267 20064 LwpnH::getWeapon()->LOADGFX(ID);
19268 20064 }
19269
19270 296065 void do_ewpnusesprite(const bool v)
19271 {
19272 296065 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19273
19274
1/2
✓ Branch 0 taken 296065 times.
✗ Branch 1 not taken.
296065 if(BC::checkWeaponMiscSprite(ID) != SH::_NoError)
19275 return;
19276
19277
1/2
✓ Branch 0 taken 296065 times.
✗ Branch 1 not taken.
296065 if(EwpnH::loadWeapon(GET_REF(ewpnref)) == SH::_NoError)
19278 296065 EwpnH::getWeapon()->LOADGFX(ID);
19279 296065 }
19280
19281 void do_portalusesprite()
19282 {
19283 int32_t ID = get_register(sarg1) / 10000;
19284
19285 if(BC::checkWeaponMiscSprite(ID) != SH::_NoError)
19286 return;
19287
19288 if(portal* p = checkPortal(GET_REF(portalref)))
19289 p->LOADGFX(ID);
19290 }
19291
19292 void do_clearsprites(const bool v)
19293 {
19294 int32_t spritelist = SH::get_arg(sarg1, v) / 10000;
19295
19296 if(BC::checkBounds(spritelist, 0, 5) != SH::_NoError)
19297 return;
19298
19299 switch(spritelist)
19300 {
19301 case 0:
19302 guys.clear();
19303 break;
19304
19305 case 1:
19306 items.clear();
19307 break;
19308
19309 case 2:
19310 Ewpns.clear();
19311 break;
19312
19313 case 3:
19314 Lwpns.clear();
19315 Hero.reset_hookshot();
19316 break;
19317
19318 case 4:
19319 decorations.clear();
19320 break;
19321
19322 case 5:
19323 particles.clear();
19324 break;
19325 }
19326 }
19327
19328 1860392 void do_loadlweapon(const bool v)
19329 {
19330 1860392 int32_t index = SH::get_arg(sarg1, v) / 10000;
19331
19332
2/2
✓ Branch 0 taken 16630 times.
✓ Branch 1 taken 1843762 times.
1860392 if(BC::checkLWeaponIndex(index) != SH::_NoError)
19333 16630 ri->lwpnref = 0; //MAX_DWORD; //Now NULL
19334 else
19335 {
19336 1843762 ri->lwpnref = Lwpns.spr(index)->getUID();
19337 // This is too trivial to log. -L
19338 }
19339 1860392 }
19340
19341 5661515 void do_loadeweapon(const bool v)
19342 {
19343 5661515 int32_t index = SH::get_arg(sarg1, v) / 10000;
19344
19345
2/2
✓ Branch 0 taken 68863 times.
✓ Branch 1 taken 5592652 times.
5661515 if(BC::checkEWeaponIndex(index) != SH::_NoError)
19346 68863 ri->ewpnref = 0; //MAX_DWORD; //Now NULL
19347 else
19348 {
19349 5592652 ri->ewpnref = Ewpns.spr(index)->getUID();
19350 }
19351 5661515 }
19352
19353 585769 void do_loaditem(const bool v)
19354 {
19355 585769 int32_t index = SH::get_arg(sarg1, v) / 10000;
19356
19357
2/2
✓ Branch 0 taken 298944 times.
✓ Branch 1 taken 286825 times.
585769 if(BC::checkItemIndex(index) != SH::_NoError)
19358 298944 ri->itemref = 0; //MAX_DWORD; //Now NULL
19359 else
19360 {
19361 286825 ri->itemref = items.spr(index)->getUID();
19362 }
19363 585769 }
19364
19365
19366 58103417 void do_loaditemdata(const bool v)
19367 {
19368 58103417 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19369
19370 //I *think* this is the right check ~Joe
19371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58103417 times.
58103417 if(BC::checkItemID(ID) != SH::_NoError)
19372 {
19373 ri->itemdataref = -1; //new null value
19374 return;
19375 }
19376 58103417 ri->itemdataref = ID;
19377 58103417 }
19378
19379 32179028 void do_loadnpc(const bool v)
19380 {
19381 32179028 int32_t index = SH::get_arg(sarg1, v) / 10000;
19382
19383
2/2
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 32178824 times.
32179028 if(BC::checkGuyIndex(index) != SH::_NoError)
19384 204 ri->npcref = 0; // MAX_DWORD;
19385 else
19386 {
19387 32178824 ri->npcref = guys.spr(index)->getUID();
19388 }
19389 32179028 }
19390
19391 1746835 void FFScript::do_loaddmapdata(const bool v)
19392 {
19393 1746835 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19394
19395
2/4
✓ Branch 0 taken 1746835 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1746835 times.
1746835 if ( ID < 0 || ID > 511 )
19396 {
19397 Z_scripterrlog("Invalid DMap ID passed to Game->LoadDMapData(): %d\n", ID);
19398 ri->dmapdataref = MAX_DWORD;
19399 }
19400 1746835 else ri->dmapdataref = ID;
19401 1746835 }
19402
19403 3 void FFScript::do_load_active_subscreendata(const bool v)
19404 {
19405 3 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19406
19407
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 if(ID == -1 || (unsigned(ID) < subscreens_active.size() && unsigned(ID) < 256))
19408 {
19409 3 ri->subscreendataref = get_subref(ID, sstACTIVE);
19410 3 }
19411 else
19412 {
19413 Z_scripterrlog("Invalid Subscreen ID passed to Game->LoadASubData(): %d\n", ID);
19414 ri->subscreendataref = 0;
19415 }
19416 3 SET_D(rEXP1, ri->subscreendataref);
19417 3 }
19418 void FFScript::do_load_passive_subscreendata(const bool v)
19419 {
19420 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19421
19422 if(ID == -1 || (unsigned(ID) < subscreens_passive.size() && unsigned(ID) < 256))
19423 {
19424 ri->subscreendataref = get_subref(ID, sstPASSIVE);
19425 }
19426 else
19427 {
19428 Z_scripterrlog("Invalid Subscreen ID passed to Game->LoadPSubData(): %d\n", ID);
19429 ri->subscreendataref = 0;
19430 }
19431 SET_D(rEXP1, ri->subscreendataref);
19432 }
19433 void FFScript::do_load_overlay_subscreendata(const bool v)
19434 {
19435 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19436
19437 if(ID == -1 || (unsigned(ID) < subscreens_overlay.size() && unsigned(ID) < 256))
19438 {
19439 ri->subscreendataref = get_subref(ID, sstOVERLAY);
19440 }
19441 else
19442 {
19443 Z_scripterrlog("Invalid Subscreen ID passed to Game->LoadOSubData(): %d\n", ID);
19444 ri->subscreendataref = 0;
19445 }
19446 SET_D(rEXP1, ri->subscreendataref);
19447 }
19448 void FFScript::do_load_map_subscreendata(const bool v)
19449 {
19450 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19451
19452 if(ID == -1 || (unsigned(ID) < subscreens_map.size() && unsigned(ID) < 256))
19453 {
19454 ri->subscreendataref = get_subref(ID, sstACTIVE);
19455 }
19456 else
19457 {
19458 Z_scripterrlog("Invalid Subscreen ID passed to Game->LoadMSubData(): %d\n", ID);
19459 ri->subscreendataref = 0;
19460 }
19461 SET_D(rEXP1, ri->subscreendataref);
19462 }
19463 3 void FFScript::do_load_subscreendata(const bool v, const bool v2)
19464 {
19465 3 int32_t ty = SH::get_arg(sarg2, v2) / 10000;
19466
1/5
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 switch(ty)
19467 {
19468 case sstACTIVE:
19469 3 do_load_active_subscreendata(v);
19470 3 break;
19471 case sstPASSIVE:
19472 do_load_passive_subscreendata(v);
19473 break;
19474 case sstOVERLAY:
19475 do_load_overlay_subscreendata(v);
19476 break;
19477 case sstMAP:
19478 do_load_map_subscreendata(v);
19479 break;
19480 default:
19481 {
19482 Z_scripterrlog("Invalid Subscreen Type passed to ???: %d\n", ty);
19483 ri->subscreendataref = 0;
19484 break;
19485 }
19486 }
19487 3 SET_D(rEXP1, ri->subscreendataref);
19488 3 }
19489
19490 932 void FFScript::do_loadrng()
19491 {
19492 932 auto rng = user_rngs.create();
19493
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 932 times.
932 if (!rng)
19494 {
19495 SET_D(rEXP1, 0);
19496 return;
19497 }
19498
19499 932 int q = script_object_ids_by_type[script_object_type::rng].size() - 1;
19500 932 rng->gen = &script_rnggens[q];
19501 932 ri->rngref = rng->id;
19502 932 SET_D(rEXP1, rng->id);
19503 932 }
19504
19505 void FFScript::do_loadstack()
19506 {
19507 ri->stackref = user_stacks.get_free();
19508 SET_D(rEXP1, ri->stackref);
19509 }
19510
19511 10 void FFScript::do_loaddropset(const bool v)
19512 {
19513 10 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19514
19515
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if ( ID < 0 || ID > MAXITEMDROPSETS )
19516 {
19517 scripting_log_error_with_context("Invalid Dropset ID: {}", ID);
19518 ri->dropsetdataref = MAX_DWORD;
19519 }
19520
19521 10 else ri->dropsetdataref = ID;
19522 10 }
19523
19524 void FFScript::do_loadbottle(const bool v)
19525 {
19526 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19527
19528 if ( ID < 1 || ID > 64 )
19529 {
19530 scripting_log_error_with_context("Invalid BottleType ID: {}", ID);
19531 ri->bottletyperef = 0;
19532 }
19533 else ri->bottletyperef = ID;
19534 }
19535
19536 void FFScript::do_loadbottleshop(const bool v)
19537 {
19538 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19539
19540 if ( ID < 0 || ID > 255 )
19541 {
19542 scripting_log_error_with_context("Invalid BottleShopType ID: {}", ID);
19543 ri->bottleshopref = 0;
19544 }
19545 else ri->bottleshopref = ID+1;
19546 }
19547 137138 void FFScript::do_loadgenericdata(const bool v)
19548 {
19549 137138 int32_t ID = SH::get_arg(sarg1, v) / 10000;
19550
19551
2/4
✓ Branch 0 taken 137138 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 137138 times.
137138 if ( ID < 1 || ID > NUMSCRIPTSGENERIC )
19552 {
19553 scripting_log_error_with_context("Invalid GenericData ID: {}", ID);
19554 ri->genericdataref = 0;
19555 }
19556 137138 else ri->genericdataref = ID;
19557 137138 }
19558
19559 223 void FFScript::do_create_paldata()
19560 {
19561 223 ri->paldataref = user_paldatas.get_free();
19562 223 SET_D(rEXP1, ri->paldataref);
19563 223 }
19564
19565 11 void FFScript::do_create_paldata_clr()
19566 {
19567 11 ri->paldataref = user_paldatas.get_free();
19568
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ri->paldataref > 0)
19569 {
19570 11 user_paldata& pd = user_paldatas[GET_REF(paldataref)];
19571 11 int32_t clri = get_register(sarg1);
19572
19573 11 RGB c = _RGB((clri >> 16) & 0xFF, (clri >> 8) & 0xFF, clri & 0xFF);
19574
19575 11 c.r = vbound(c.r, 0, scripting_max_color_val);
19576 11 c.g = vbound(c.g, 0, scripting_max_color_val);
19577 11 c.b = vbound(c.b, 0, scripting_max_color_val);
19578
19579
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 11 times.
2651 for (int32_t q = 0; q < 240; ++q)
19580 2640 pd.set_color(q, c);
19581 11 }
19582 11 SET_D(rEXP1, ri->paldataref);
19583 11 }
19584
19585 void FFScript::do_mix_clr()
19586 {
19587 int32_t clr_start = SH::read_stack(ri->sp + 3);
19588 int32_t clr_end = SH::read_stack(ri->sp + 2);
19589 float percent = SH::read_stack(ri->sp + 1) / 10000.0;
19590 int32_t color_space = SH::read_stack(ri->sp + 0) / 10000;
19591
19592 RGB ref1c = _RGB((clr_start >> 16) & 0xFF, (clr_start >> 8) & 0xFF, clr_start & 0xFF);
19593 RGB ref2c = _RGB((clr_end >> 16) & 0xFF, (clr_end >> 8) & 0xFF, clr_end & 0xFF);
19594 RGB outputc = user_paldata::mix_color(ref1c, ref2c, percent, color_space);
19595
19596 int32_t r = vbound(outputc.r, 0, scripting_max_color_val);
19597 int32_t g = vbound(outputc.g, 0, scripting_max_color_val);
19598 int32_t b = vbound(outputc.b, 0, scripting_max_color_val);
19599
19600 SET_D(rEXP1, (r << 16) | (g << 8) | b);
19601 }
19602
19603 void FFScript::do_create_rgb_hex()
19604 {
19605 int32_t hexrgb = get_register(sarg1);
19606
19607 int32_t r = (hexrgb >> 16) & 0xFF;
19608 int32_t g = (hexrgb >> 8) & 0xFF;
19609 int32_t b = hexrgb & 0xFF;
19610
19611 if (scripting_use_8bit_colors)
19612 {
19613 r = vbound(r, 0, 255);
19614 g = vbound(g, 0, 255);
19615 b = vbound(b, 0, 255);
19616 }
19617 else
19618 {
19619 r = vbound(r / 4, 0, 63);
19620 g = vbound(g / 4, 0, 63);
19621 b = vbound(b / 4, 0, 63);
19622 }
19623
19624 SET_D(rEXP1, (r << 16) | (g << 8) | b);
19625 }
19626
19627 11 void FFScript::do_create_rgb()
19628 {
19629 11 int32_t r = SH::read_stack(ri->sp + 2) / 10000;
19630 11 int32_t g = SH::read_stack(ri->sp + 1) / 10000;
19631 11 int32_t b = SH::read_stack(ri->sp + 0) / 10000;
19632
19633 11 int max_value = scripting_max_color_val;
19634
4/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
11 if (unsigned(r) > max_value || unsigned(g) > max_value || unsigned(b) > max_value)
19635 {
19636 1 scripting_log_error_with_context("R/G/B values should range from 0-{}, got: {} {} {}", max_value, r, g, b);
19637 1 }
19638
19639 11 r = vbound(r, 0, max_value);
19640 11 g = vbound(g, 0, max_value);
19641 11 b = vbound(b, 0, max_value);
19642
19643 11 SET_D(rEXP1, (r << 16) | (g << 8) | b);
19644 11 }
19645
19646 void FFScript::do_convert_from_rgb()
19647 {
19648 int32_t buf = SH::read_stack(ri->sp + 2) / 10000;
19649 int32_t clri = SH::read_stack(ri->sp + 1);
19650 int32_t color_space = SH::read_stack(ri->sp + 0) / 10000;
19651
19652 ArrayManager am(buf);
19653 if (am.invalid()) return;
19654 int32_t zscript_array_size = am.size();
19655 int32_t target_size;
19656
19657 switch (color_space)
19658 {
19659 case user_paldata::CSPACE_CMYK:
19660 target_size = 4;
19661 break;
19662 default:
19663 target_size = 3;
19664 }
19665
19666 if (zscript_array_size < target_size)
19667 {
19668 scripting_log_error_with_context("Array not large enough. Should be at least size {}", target_size);
19669 return;
19670 }
19671
19672 RGB c = _RGB((clri >> 16) & 0xFF, (clri >> 8) & 0xFF, clri & 0xFF);
19673 double convert[4];
19674 user_paldata::RGBTo(c, convert, color_space);
19675
19676 for (int32_t q = 0; q < target_size; ++q)
19677 {
19678 am.set(q, int32_t(convert[q]*10000));
19679 }
19680
19681 return;
19682 }
19683
19684 void FFScript::do_convert_to_rgb()
19685 {
19686 int32_t buf = SH::read_stack(ri->sp + 1) / 10000;
19687 int32_t color_space = SH::read_stack(ri->sp + 0) / 10000;
19688
19689 ArrayManager am(buf);
19690 if (am.invalid()) return;
19691 int32_t zscript_array_size = am.size();
19692 int32_t target_size;
19693
19694 switch (color_space)
19695 {
19696 case user_paldata::CSPACE_CMYK:
19697 target_size = 4;
19698 break;
19699 default:
19700 target_size = 3;
19701 }
19702
19703 if (zscript_array_size < target_size)
19704 {
19705 scripting_log_error_with_context("Array not large enough. Should be at least size {}", target_size);
19706 return;
19707 }
19708
19709 double convert[4];
19710 for (int32_t q = 0; q < target_size; ++q)
19711 {
19712 convert[q] = am.get(q) / 10000.0;
19713 }
19714 RGB c = user_paldata::RGBFrom(convert, color_space);
19715
19716 SET_D(rEXP1, (c.r << 16) | (c.g << 8) | c.b);
19717 }
19718
19719 24 void FFScript::do_paldata_load_level()
19720 {
19721
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19722 {
19723 24 int32_t lvl = get_register(sarg1) / 10000;
19724 //Load CSets 2-4
19725 24 pd->load_cset(2, lvl * pdLEVEL + poLEVEL + 0);
19726 24 pd->load_cset(3, lvl * pdLEVEL + poLEVEL + 1);
19727 24 pd->load_cset(4, lvl * pdLEVEL + poLEVEL + 2);
19728 //Load CSet 9
19729 24 pd->load_cset(9, lvl * pdLEVEL + poLEVEL + 3);
19730 //Load 1, 5, 7, 8
19731 24 pd->load_cset(1, lvl * pdLEVEL + poNEWCSETS);
19732 24 pd->load_cset(5, lvl * pdLEVEL + poNEWCSETS + 1);
19733 24 pd->load_cset(7, lvl * pdLEVEL + poNEWCSETS + 2);
19734 24 pd->load_cset(8, lvl * pdLEVEL + poNEWCSETS + 3);
19735 24 }
19736 24 return;
19737 }
19738
19739 87 void FFScript::do_paldata_load_sprite()
19740 {
19741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 87 times.
87 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19742 {
19743 87 int32_t page = get_register(sarg1) / 10000;
19744
19745 87 int32_t pageoffset = 0;
19746
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 87 times.
✗ Branch 2 not taken.
87 switch (page)
19747 {
19748 87 case 0: pageoffset += 0; break;
19749 case 1: pageoffset += 15; break;
19750 default:
19751 scripting_log_error_with_context("Invalid page: {}. Valid pages are 0 or 1. Aborting.", page);
19752 return;
19753 }
19754
2/2
✓ Branch 0 taken 1305 times.
✓ Branch 1 taken 87 times.
1392 for (int32_t q = 0; q < 15; ++q)
19755 {
19756 1305 pd->load_cset(q, poSPRITE255 + pageoffset + q);
19757 1305 }
19758 87 }
19759 87 return;
19760 87 }
19761
19762 92 void FFScript::do_paldata_load_main()
19763 {
19764
1/2
✓ Branch 0 taken 92 times.
✗ Branch 1 not taken.
92 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19765 {
19766
2/2
✓ Branch 0 taken 1472 times.
✓ Branch 1 taken 92 times.
1564 for (int32_t q = 0; q <= 15; ++q)
19767 {
19768 1472 pd->load_cset_main(q);
19769 1472 }
19770 92 }
19771 92 return;
19772 }
19773
19774 void FFScript::do_paldata_load_cycle()
19775 {
19776 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19777 {
19778 int32_t lvl = get_register(sarg1) / 10000;
19779 for (int32_t q = 4; q <= 12; ++q)
19780 {
19781 pd->load_cset(q, lvl * pdLEVEL + poLEVEL + q);
19782 }
19783 }
19784 return;
19785 }
19786
19787 void FFScript::do_paldata_load_bitmap()
19788 {
19789 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19790 {
19791 int32_t pathptr = get_register(sarg1);
19792 string user_path, str;
19793 ArrayH::getString(pathptr, user_path, 256);
19794
19795 if (get_qr(qr_BITMAP_AND_FILESYSTEM_PATHS_ALWAYS_RELATIVE))
19796 {
19797 if (auto r = parse_user_path(user_path, true); !r)
19798 {
19799 scripting_log_error_with_context("Error: {}", r.error());
19800 return;
19801 } else str = r.value();
19802 }
19803 else
19804 {
19805 str = user_path;
19806 regulate_path(str);
19807 }
19808
19809 if (str.empty())
19810 {
19811 al_trace("String pointer is null! Internal error. \n");
19812 return;
19813 }
19814
19815 PALETTE tempPal;
19816 get_palette(tempPal);
19817 if (checkPath(str.c_str(), false))
19818 {
19819 BITMAP* bmp = load_bitmap(str.c_str(), tempPal);
19820 if (!bmp)
19821 {
19822 Z_scripterrlog("LoadBitmapPalette() failed to load image file %s.\n", str.c_str());
19823 }
19824 else
19825 {
19826 for (int32_t q = 0; q < PALDATA_NUM_COLORS; ++q)
19827 {
19828 pd->colors[q] = tempPal[q];
19829 set_bit(pd->colors_used, q, true);
19830 }
19831 }
19832 destroy_bitmap(bmp);
19833 }
19834 else
19835 {
19836 Z_scripterrlog("Failed to load image file: %s. File not found.\n", str.c_str());
19837 }
19838 }
19839 return;
19840 }
19841
19842 370 void FFScript::do_paldata_write_level()
19843 {
19844
1/2
✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
370 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19845 {
19846 370 int32_t lvl = get_register(sarg1) / 10000;
19847 370 bool changed = false;
19848 //Write CSets 2-4
19849
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(2, lvl * pdLEVEL + poLEVEL + 0))
19850 {
19851 360 pd->write_cset(2, lvl * pdLEVEL + poLEVEL + 0);
19852 360 changed = true;
19853 360 }
19854
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(3, lvl * pdLEVEL + poLEVEL + 1))
19855 {
19856 360 pd->write_cset(3, lvl * pdLEVEL + poLEVEL + 1);
19857 360 changed = true;
19858 360 }
19859
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(4, lvl * pdLEVEL + poLEVEL + 2))
19860 {
19861 360 pd->write_cset(4, lvl * pdLEVEL + poLEVEL + 2);
19862 360 changed = true;
19863 360 }
19864 //Write CSet 9
19865
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(9, lvl * pdLEVEL + poLEVEL + 3))
19866 {
19867 360 pd->write_cset(9, lvl * pdLEVEL + poLEVEL + 3);
19868 360 changed = true;
19869 360 }
19870 //Write 1, 5, 7, 8
19871
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(1, lvl * pdLEVEL + poNEWCSETS + 0))
19872 {
19873 360 pd->write_cset(1, lvl * pdLEVEL + poNEWCSETS + 0);
19874 360 changed = true;
19875 360 }
19876
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(5, lvl * pdLEVEL + poNEWCSETS + 1))
19877 {
19878 360 pd->write_cset(5, lvl * pdLEVEL + poNEWCSETS + 1);
19879 360 changed = true;
19880 360 }
19881
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(7, lvl * pdLEVEL + poNEWCSETS + 2))
19882 {
19883 360 pd->write_cset(7, lvl * pdLEVEL + poNEWCSETS + 2);
19884 360 changed = true;
19885 360 }
19886
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 360 times.
370 if (pd->check_cset(8, lvl * pdLEVEL + poNEWCSETS + 3))
19887 {
19888 360 pd->write_cset(8, lvl * pdLEVEL + poNEWCSETS + 3);
19889 360 changed = true;
19890 360 }
19891
19892
4/4
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 350 times.
370 if (changed && DMaps[cur_dmap].color == lvl)
19893 {
19894 350 loadlvlpal(lvl);
19895 350 currcset = lvl;
19896
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 350 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
350 if (darkroom && !get_qr(qr_NEW_DARKROOM))
19897 {
19898 if (get_qr(qr_FADE))
19899 {
19900 interpolatedfade();
19901 }
19902 else
19903 {
19904 loadfadepal((DMaps[cur_dmap].color) * pdLEVEL + poFADE3);
19905 }
19906 }
19907 350 }
19908 370 }
19909 370 return;
19910 }
19911
19912 void FFScript::do_paldata_write_levelcset()
19913 {
19914 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
19915 {
19916 int32_t lvl = get_register(sarg1) / 10000;
19917 int32_t cs = get_register(sarg2) / 10000;
19918
19919 bool changed = false;
19920
19921 switch (cs)
19922 {
19923 case 1:
19924 if (pd->check_cset(1, lvl * pdLEVEL + poNEWCSETS + 0))
19925 {
19926 pd->write_cset(1, lvl * pdLEVEL + poNEWCSETS + 0);
19927 changed = true;
19928 }
19929 break;
19930 case 2:
19931 if (pd->check_cset(2, lvl * pdLEVEL + poLEVEL + 0))
19932 {
19933 pd->write_cset(2, lvl * pdLEVEL + poLEVEL + 0);
19934 changed = true;
19935 }
19936 break;
19937 case 3:
19938 if (pd->check_cset(3, lvl * pdLEVEL + poLEVEL + 1))
19939 {
19940 pd->write_cset(3, lvl * pdLEVEL + poLEVEL + 1);
19941 changed = true;
19942 }
19943 break;
19944 case 4:
19945 if (pd->check_cset(4, lvl * pdLEVEL + poLEVEL + 2))
19946 {
19947 pd->write_cset(4, lvl * pdLEVEL + poLEVEL + 2);
19948 changed = true;
19949 }
19950 break;
19951 case 5:
19952 if (pd->check_cset(5, lvl * pdLEVEL + poNEWCSETS + 1))
19953 {
19954 pd->write_cset(5, lvl * pdLEVEL + poNEWCSETS + 1);
19955 changed = true;
19956 }
19957 break;
19958 case 7:
19959 if (pd->check_cset(7, lvl * pdLEVEL + poNEWCSETS + 2))
19960 {
19961 pd->write_cset(7, lvl * pdLEVEL + poNEWCSETS + 2);
19962 changed = true;
19963 }
19964 break;
19965 case 8:
19966 if (pd->check_cset(8, lvl * pdLEVEL + poNEWCSETS + 3))
19967 {
19968 pd->write_cset(8, lvl * pdLEVEL + poNEWCSETS + 3);
19969 changed = true;
19970 }
19971 break;
19972 case 9:
19973 if (pd->check_cset(9, lvl * pdLEVEL + poLEVEL + 3))
19974 {
19975 pd->write_cset(9, lvl * pdLEVEL + poLEVEL + 3);
19976 changed = true;
19977 }
19978 break;
19979 default:
19980 Z_scripterrlog("Invalid CSet (%d) passed to 'paldata->WriteLevelCSet()'. Level palettes can use CSets 1, 2, 3, 4, 5, 7, 8, 9.\n", cs);
19981 return;
19982 }
19983
19984 if (changed && DMaps[cur_dmap].color == lvl)
19985 {
19986 loadlvlpal(lvl);
19987 if (darkroom && !get_qr(qr_NEW_DARKROOM))
19988 {
19989 if (get_qr(qr_FADE))
19990 {
19991 interpolatedfade();
19992 }
19993 else
19994 {
19995 loadfadepal((DMaps[cur_dmap].color) * pdLEVEL + poFADE3);
19996 }
19997 }
19998 currcset = lvl;
19999 }
20000 }
20001 }
20002
20003 31 void FFScript::do_paldata_write_sprite()
20004 {
20005
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20006 {
20007 31 int32_t page = get_register(sarg1) / 10000;
20008
20009 31 int32_t pageoffset = 0;
20010
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
31 switch (page)
20011 {
20012 31 case 0: pageoffset += 0; break;
20013 case 1: pageoffset += 15; break;
20014 default:
20015 Z_scripterrlog("Invalid page (%d) passed to paldata->WriteSpritePalette(). Valid pages are 0 or 1. Aborting.\n", page);
20016 return;
20017 }
20018 31 bool changed6 = false;
20019 31 bool changed14 = false;
20020
2/2
✓ Branch 0 taken 465 times.
✓ Branch 1 taken 31 times.
496 for (int32_t q = 0; q < 15; ++q)
20021 {
20022
2/2
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 25 times.
465 if (pd->check_cset(q, poSPRITE255 + pageoffset + q))
20023 {
20024 25 pd->write_cset(q, poSPRITE255 + pageoffset + q);
20025
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (pageoffset + q == currspal6)
20026 {
20027 changed6 = true;
20028 }
20029
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (pageoffset + q == currspal14)
20030 {
20031 changed14 = true;
20032 }
20033 25 }
20034 465 }
20035
20036 //If either sprite palette has been changed, update the main palette
20037
2/4
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 31 times.
31 if (changed6 || changed14)
20038 {
20039 if (changed6)
20040 {
20041 loadpalset(6, poSPRITE255 + currspal6, false);
20042 }
20043 if (changed14)
20044 {
20045 loadpalset(14, poSPRITE255 + currspal14, false);
20046 }
20047
20048 if (isUserTinted()) {
20049 restoreTint();
20050 }
20051 }
20052 31 }
20053 31 return;
20054 31 }
20055
20056 void FFScript::do_paldata_write_spritecset()
20057 {
20058 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20059 {
20060 int32_t page = get_register(sarg1) / 10000;
20061 int32_t cs = get_register(sarg2) / 10000;
20062
20063 int32_t pageoffset = 0;
20064 switch (page)
20065 {
20066 case 0: pageoffset += 0; break;
20067 case 1: pageoffset += 15; break;
20068 default:
20069 Z_scripterrlog("Invalid page (%d) passed to paldata->WriteSpriteCSet(). Valid pages are 0 or 1. Aborting.\n", page);
20070 return;
20071 }
20072 bool changed6 = false;
20073 bool changed14 = false;
20074 if (unsigned(cs) > 15)
20075 {
20076 Z_scripterrlog("Invalid CSet (%d) passed to paldata->WriteSpriteCSet(). Valid CSets are 0-15. Aborting.\n", cs);
20077 return;
20078 }
20079 if (pd->check_cset(cs, poSPRITE255 + pageoffset + cs))
20080 {
20081 pd->write_cset(cs, poSPRITE255 + pageoffset + cs);
20082 if (pageoffset + cs == currspal6)
20083 {
20084 changed6 = true;
20085 }
20086 if (pageoffset + cs == currspal14)
20087 {
20088 changed14 = true;
20089 }
20090 }
20091
20092 //If either sprite palette has been changed, update the main palette
20093 if (changed6 || changed14)
20094 {
20095 if (changed6)
20096 {
20097 loadpalset(6, poSPRITE255 + currspal6, false);
20098 }
20099 if (changed14)
20100 {
20101 loadpalset(14, poSPRITE255 + currspal14, false);
20102 }
20103
20104 if (isUserTinted()) {
20105 restoreTint();
20106 }
20107 }
20108 }
20109 return;
20110 }
20111
20112 1064 void FFScript::do_paldata_write_main()
20113 {
20114
1/2
✓ Branch 0 taken 1064 times.
✗ Branch 1 not taken.
1064 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20115 {
20116 1064 bool changed = false;
20117
2/2
✓ Branch 0 taken 17024 times.
✓ Branch 1 taken 1064 times.
18088 for (int32_t q = 0; q <= 15; ++q)
20118 {
20119
2/2
✓ Branch 0 taken 11363 times.
✓ Branch 1 taken 5661 times.
17024 if (pd->check_cset_main(q))
20120 {
20121 5661 pd->write_cset_main(q);
20122 5661 changed = true;
20123 5661 }
20124 17024 }
20125
20126
2/2
✓ Branch 0 taken 332 times.
✓ Branch 1 taken 732 times.
1064 if (changed)
20127 {
20128 732 refreshpal = true;
20129 732 }
20130 1064 }
20131 1064 return;
20132 }
20133
20134 130 void FFScript::do_paldata_write_maincset()
20135 {
20136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 130 times.
130 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20137 {
20138 130 int32_t cs = get_register(sarg1) / 10000;
20139
20140 130 bool changed = false;
20141
20142
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 if (unsigned(cs) < 16)
20143 {
20144
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 if (pd->check_cset_main(cs))
20145 {
20146 130 pd->write_cset_main(cs);
20147 130 changed = true;
20148 130 }
20149 130 }
20150 else
20151 {
20152 Z_scripterrlog("Invalid CSet (%d) passed to 'paldata->WriteMainCSet()'. Valid csets are 0-15. Aborting.\n", cs);
20153 return;
20154 }
20155
20156
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 if (changed)
20157 {
20158 130 refreshpal = true;
20159 130 }
20160 130 }
20161 130 }
20162
20163 void FFScript::do_paldata_write_cycle()
20164 {
20165 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20166 {
20167 int32_t lvl = get_register(sarg1) / 10000;
20168 for (int32_t q = 4; q <= 12; ++q)
20169 {
20170 if (pd->check_cset(q, lvl * pdLEVEL + poLEVEL + q))
20171 {
20172 pd->write_cset(q, lvl * pdLEVEL + poLEVEL + q);
20173 }
20174 }
20175 }
20176 return;
20177 }
20178
20179 void FFScript::do_paldata_write_cyclecset()
20180 {
20181 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20182 {
20183 int32_t lvl = get_register(sarg1) / 10000;
20184 int32_t cs = get_register(sarg2) / 10000;
20185
20186 bool changed = false;
20187
20188 switch (cs)
20189 {
20190 case 4:
20191 case 5:
20192 case 6:
20193 case 7:
20194 case 8:
20195 case 9:
20196 case 10:
20197 case 11:
20198 case 12:
20199 if (pd->check_cset(cs, lvl * pdLEVEL + poLEVEL + cs))
20200 {
20201 pd->write_cset(cs, lvl * pdLEVEL + poLEVEL + cs);
20202 changed = true;
20203 }
20204 break;
20205 default:
20206 Z_scripterrlog("Invalid CSet (%d) passed to 'paldata->WriteCycleCSet()'. Cycle palettes use CSets 4-12.\n", cs);
20207 return;
20208 }
20209
20210 if (changed && DMaps[cur_dmap].color == lvl)
20211 {
20212 loadlvlpal(lvl);
20213 currcset = lvl;
20214 }
20215 }
20216 }
20217
20218 void FFScript::do_paldata_colorvalid()
20219 {
20220 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20221 {
20222 int32_t ind = get_register(sarg1) / 10000;
20223 if (unsigned(ind) >= PALDATA_NUM_COLORS)
20224 {
20225 Z_scripterrlog("Invalid color index (%d) passed to paldata->ColorValid(). Valid indices are 0-255.\n", ind);
20226 set_register(sarg1, 0);
20227 return;
20228 }
20229
20230 if (get_bit(pd->colors_used, ind))
20231 {
20232 set_register(sarg1, 10000);
20233 }
20234 else
20235 {
20236 set_register(sarg1, 0);
20237 }
20238 }
20239 }
20240
20241 void FFScript::do_paldata_clearcolor()
20242 {
20243 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20244 {
20245 int32_t ind = get_register(sarg1) / 10000;
20246 if (unsigned(ind) >= PALDATA_NUM_COLORS)
20247 {
20248 Z_scripterrlog("Invalid color index (%d) passed to paldata->ClearColor(). Valid indices are 0-255. Aborting.\n", ind);
20249 return;
20250 }
20251 set_bit(pd->colors_used, ind, false);
20252 }
20253 }
20254
20255 void FFScript::do_paldata_clearcset()
20256 {
20257 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20258 {
20259 int32_t cs = get_register(sarg1) / 10000;
20260 if (unsigned(cs) > 15)
20261 {
20262 Z_scripterrlog("Invalid cset (%d) passed to paldata->ClearCSet(). Valid csets are 0-15. Aborting.\n", cs);
20263 return;
20264 }
20265 for (int32_t q = 0; q < 16; ++q)
20266 {
20267 set_bit(pd->colors_used, CSET(cs) + q, false);
20268 }
20269 }
20270 }
20271
20272 int32_t FFScript::do_paldata_getrgb(user_paldata* pd, int32_t index, int32_t c)
20273 {
20274 if (pd)
20275 {
20276 int32_t ind = index;
20277 if (unsigned(ind) >= PALDATA_NUM_COLORS)
20278 {
20279 scripting_log_error_with_context("Invalid color index ({}). Valid indices are 0-255.", ind);
20280 return -10000;
20281 }
20282 if (!get_bit(pd->colors_used, ind))
20283 {
20284 scripting_log_error_with_context("Tried to access unused color {}.", ind);
20285 return -10000;
20286 }
20287 switch (c)
20288 {
20289 case 0:
20290 return pd->colors[ind].r * 10000;
20291 case 1:
20292 return pd->colors[ind].g * 10000;
20293 case 2:
20294 return pd->colors[ind].b * 10000;
20295 }
20296 }
20297
20298 return -10000;
20299 }
20300
20301 void FFScript::do_paldata_setrgb(user_paldata* pd, int32_t index, int32_t val, int32_t c)
20302 {
20303 if (pd)
20304 {
20305 int32_t ind = index;
20306 if (unsigned(ind) >= PALDATA_NUM_COLORS)
20307 {
20308 scripting_log_error_with_context("Invalid color index ({}). Valid indices are 0-255. Aborting.", ind);
20309 return;
20310 }
20311 if (unsigned(val) > scripting_max_color_val)
20312 {
20313 scripting_log_error_with_context("RGB value({}) is out of range. RGB values range from 0 - {}.", val, scripting_max_color_val);
20314 val = vbound(val, 0, scripting_max_color_val);
20315 }
20316 if (!get_bit(pd->colors_used, ind))
20317 {
20318 scripting_log_error_with_context("Tried to access unused color {}.", ind);
20319 return;
20320 }
20321 switch (c)
20322 {
20323 case 0:
20324 pd->colors[ind].r = val;
20325 break;
20326 case 1:
20327 pd->colors[ind].g = val;
20328 break;
20329 case 2:
20330 pd->colors[ind].b = val;
20331 break;
20332 }
20333 }
20334 }
20335
20336 450 void FFScript::do_paldata_mix()
20337 {
20338 450 int32_t ref = SH::read_stack(ri->sp + 4);
20339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if (user_paldata* pd = checkPalData(ref))
20340 {
20341 450 int32_t ref1 = SH::read_stack(ri->sp + 3);
20342 450 int32_t ref2 = SH::read_stack(ri->sp + 2);
20343 450 double percent = SH::read_stack(ri->sp + 1)/10000.0;
20344 450 int32_t color_space = SH::read_stack(ri->sp + 0)/10000;
20345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if (user_paldata* pd_start = checkPalData(ref1))
20346 {
20347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if (user_paldata* pd_end = checkPalData(ref2))
20348 {
20349 450 pd->mix(pd_start, pd_end, percent, color_space);
20350 450 }
20351 450 }
20352 450 }
20353 450 }
20354
20355 4781 void FFScript::do_paldata_mixcset()
20356 {
20357 4781 int32_t ref = SH::read_stack(ri->sp + 5);
20358
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4781 times.
4781 if (user_paldata* pd = checkPalData(ref))
20359 {
20360 4781 int32_t ref1 = SH::read_stack(ri->sp + 4);
20361 4781 int32_t ref2 = SH::read_stack(ri->sp + 3);
20362 4781 int32_t cset = SH::read_stack(ri->sp + 2) / 10000;
20363 4781 double percent = SH::read_stack(ri->sp + 1) / 10000.0;
20364 4781 int32_t color_space = SH::read_stack(ri->sp + 0) / 10000;
20365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4781 times.
4781 if (user_paldata* pd_start = checkPalData(ref1))
20366 {
20367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4781 times.
4781 if (user_paldata* pd_end = checkPalData(ref2))
20368 {
20369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4781 times.
4781 if (unsigned(cset) > 15)
20370 {
20371 Z_scripterrlog("CSet passed to 'paldata->MixCSet()' out of range. Valid CSets are 0-15\n");
20372 return;
20373 }
20374 4781 pd->mix(pd_start, pd_end, percent, color_space, CSET(cset), CSET(cset) + 16);
20375 4781 }
20376 4781 }
20377 4781 }
20378 4781 }
20379
20380 void FFScript::do_paldata_copy()
20381 {
20382 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20383 {
20384 int32_t ref_dest = get_register(sarg1);
20385 if (user_paldata* pd_dest = checkPalData(ref_dest))
20386 {
20387 for (int32_t q = 0; q < PALDATA_NUM_COLORS; ++q)
20388 {
20389 pd_dest->colors[q] = pd->colors[q];
20390 }
20391 for (int32_t q = 0; q < PALDATA_BITSTREAM_SIZE; ++q)
20392 {
20393 pd_dest->colors_used[q] = pd->colors_used[q];
20394 }
20395 }
20396 }
20397 }
20398
20399 112 void FFScript::do_paldata_copycset()
20400 {
20401 112 ri->paldataref = SH::read_stack(ri->sp + 3);
20402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (user_paldata* pd = checkPalData(GET_REF(paldataref)))
20403 {
20404 112 int32_t ref_dest = SH::read_stack(ri->sp + 2);
20405 112 int32_t cs = SH::read_stack(ri->sp + 1) / 10000;
20406 112 int32_t cs_dest = SH::read_stack(ri->sp + 0) / 10000;
20407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (user_paldata* pd_dest = checkPalData(ref_dest))
20408 {
20409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (unsigned(cs) > 15)
20410 {
20411 Z_scripterrlog("Invalid CSet (%d) passed to paldata->CopyCSet(). Valid CSets are 0-15. Aborting.\n", cs);
20412 return;
20413 }
20414
2/2
✓ Branch 0 taken 1792 times.
✓ Branch 1 taken 112 times.
1904 for (int32_t q = 0; q < 16; ++q)
20415 {
20416 1792 pd_dest->colors[CSET(cs_dest) + q] = pd->colors[CSET(cs) + q];
20417 1792 set_bit(pd_dest->colors_used, CSET(cs_dest) + q, bool(get_bit(pd->colors_used, CSET(cs) + q)));
20418 1792 }
20419 112 }
20420 112 }
20421 112 }
20422
20423 //Loads a cset to paldata from memory
20424 1497 void user_paldata::load_cset(int32_t cset, int32_t dataset)
20425 {
20426 1497 byte* si = colordata + CSET(dataset) * 3;
20427
2/2
✓ Branch 0 taken 23952 times.
✓ Branch 1 taken 1497 times.
25449 for (int32_t q = 0; q < 16; ++q)
20428 {
20429 23952 int32_t ind = CSET(cset) + q;
20430 23952 colors[ind].r = scripting_read_pal_color(si[0]);
20431 23952 colors[ind].g = scripting_read_pal_color(si[1]);
20432 23952 colors[ind].b = scripting_read_pal_color(si[2]);
20433 23952 set_bit(colors_used, ind, true);
20434 23952 si += 3;
20435 23952 }
20436 1497 }
20437
20438 //Loads a cset to paldata from the main palette
20439 1472 void user_paldata::load_cset_main(int32_t cset)
20440 {
20441
2/2
✓ Branch 0 taken 23552 times.
✓ Branch 1 taken 1472 times.
25024 for (int32_t q = 0; q < 16; ++q)
20442 {
20443 23552 int32_t ind = CSET(cset) + q;
20444 23552 colors[ind].r = scripting_read_pal_color(RAMpal[ind].r);
20445 23552 colors[ind].g = scripting_read_pal_color(RAMpal[ind].g);
20446 23552 colors[ind].b = scripting_read_pal_color(RAMpal[ind].b);
20447 23552 set_bit(colors_used, ind, true);
20448 23552 }
20449 1472 }
20450
20451 //Writes to a memory cset from paldata
20452 2905 void user_paldata::write_cset(int32_t cset, int32_t dataset)
20453 {
20454 2905 byte* si = colordata + CSET(dataset) * 3;
20455
2/2
✓ Branch 0 taken 46480 times.
✓ Branch 1 taken 2905 times.
49385 for (int32_t q = 0; q < 16; ++q)
20456 {
20457 46480 int32_t ind = CSET(cset) + q;
20458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46480 times.
46480 if (get_bit(colors_used, ind))
20459 {
20460 46480 si[0] = scripting_write_pal_color(colors[ind].r);
20461 46480 si[1] = scripting_write_pal_color(colors[ind].g);
20462 46480 si[2] = scripting_write_pal_color(colors[ind].b);
20463 46480 }
20464 46480 si += 3;
20465 46480 }
20466 2905 }
20467
20468 //Writes to a main palette cset from paldata
20469 5791 void user_paldata::write_cset_main(int32_t cset)
20470 {
20471
2/2
✓ Branch 0 taken 92656 times.
✓ Branch 1 taken 5791 times.
98447 for (int32_t q = 0; q < 16; ++q)
20472 {
20473 92656 int32_t ind = CSET(cset) + q;
20474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92656 times.
92656 if (get_bit(colors_used, ind))
20475 {
20476 92656 RAMpal[ind] = colors[ind];
20477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92656 times.
92656 if (!scripting_use_8bit_colors)
20478 92656 convertRGB(RAMpal[ind]);
20479 92656 }
20480 92656 }
20481 5791 }
20482
20483
20484 //Checks a memory cset from
20485
20486
20487
20488
20489 3425 bool user_paldata::check_cset(int32_t cset, int32_t dataset)
20490 {
20491 3425 byte* si = colordata + CSET(dataset) * 3;
20492
2/2
✓ Branch 0 taken 11375 times.
✓ Branch 1 taken 520 times.
11895 for (int32_t q = 0; q < 16; ++q)
20493 {
20494 11375 int32_t ind = CSET(cset) + q;
20495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11375 times.
11375 if (get_bit(colors_used, ind))
20496 {
20497
2/2
✓ Branch 0 taken 9482 times.
✓ Branch 1 taken 1893 times.
11375 if (scripting_read_pal_color(si[0]) != colors[ind].r)
20498 1893 return true;
20499
2/2
✓ Branch 0 taken 8470 times.
✓ Branch 1 taken 1012 times.
9482 if (scripting_read_pal_color(si[1]) != colors[ind].g)
20500 1012 return true;
20501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8470 times.
8470 if (scripting_read_pal_color(si[2]) != colors[ind].b)
20502 return true;
20503 8470 }
20504 8470 si += 3;
20505 8470 }
20506 520 return false;
20507 3425 }
20508
20509 //Checks a memory cset from the main palette
20510 17154 bool user_paldata::check_cset_main(int32_t cset)
20511 {
20512
2/2
✓ Branch 0 taken 188844 times.
✓ Branch 1 taken 11363 times.
200207 for (int32_t q = 0; q < 16; ++q)
20513 {
20514 188844 int32_t ind = CSET(cset) + q;
20515
2/2
✓ Branch 0 taken 96064 times.
✓ Branch 1 taken 92780 times.
188844 if (get_bit(colors_used, ind))
20516 {
20517
2/2
✓ Branch 0 taken 88937 times.
✓ Branch 1 taken 3843 times.
92780 if (scripting_read_pal_color(RAMpal[ind].r) != colors[ind].r)
20518 3843 return true;
20519
2/2
✓ Branch 0 taken 87200 times.
✓ Branch 1 taken 1737 times.
88937 if (scripting_read_pal_color(RAMpal[ind].g) != colors[ind].g)
20520 1737 return true;
20521
2/2
✓ Branch 0 taken 211 times.
✓ Branch 1 taken 86989 times.
87200 if (scripting_read_pal_color(RAMpal[ind].b) != colors[ind].b)
20522 211 return true;
20523 86989 }
20524 183053 }
20525 11363 return false;
20526 17154 }
20527
20528 //Mixes a color between two paldatas
20529 139696 RGB user_paldata::mix_color(RGB start, RGB end, double percent, int32_t color_space)
20530 {
20531 139696 double upper = scripting_max_color_val;
20532 139696 int32_t direction = 0;
20533
1/13
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 139696 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
139696 switch (color_space)
20534 {
20535 case CSPACE_RGB:
20536 279392 return _RGB(byte(vbound(double(zc::math::Lerp(start.r, end.r, percent)), 0.0, upper)),
20537 139696 byte(vbound(double(zc::math::Lerp(start.g, end.g, percent)), 0.0, upper)),
20538 139696 byte(vbound(double(zc::math::Lerp(start.b, end.b, percent)), 0.0, upper)));
20539 case CSPACE_CMYK:
20540 {
20541 double convert_start[4];
20542 double convert_end[4];
20543 double convert_result[4];
20544 RGBTo(start, convert_start, color_space);
20545 RGBTo(end, convert_end, color_space);
20546 convert_result[0] = zc::math::Lerp(convert_start[0], convert_end[0], percent);
20547 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20548 convert_result[2] = zc::math::Lerp(convert_start[2], convert_end[2], percent);
20549 convert_result[3] = zc::math::Lerp(convert_start[3], convert_end[3], percent);
20550 return RGBFrom(convert_result, color_space);
20551 }
20552 case CSPACE_HSV_CW:
20553 if (color_space == CSPACE_HSV_CW)
20554 direction = 1;
20555 [[fallthrough]];
20556 case CSPACE_HSV_CCW:
20557 if (color_space == CSPACE_HSV_CCW)
20558 direction = -1;
20559 [[fallthrough]];
20560 case CSPACE_HSV:
20561 {
20562 double convert_start[3];
20563 double convert_end[3];
20564 double convert_result[3];
20565 RGBTo(start, convert_start, color_space);
20566 RGBTo(end, convert_end, color_space);
20567 convert_result[0] = WrapLerp(convert_start[0], convert_end[0], percent, 0.0, 1.0, direction);
20568 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20569 convert_result[2] = zc::math::Lerp(convert_start[2], convert_end[2], percent);
20570 return RGBFrom(convert_result, color_space);
20571 }
20572 case CSPACE_HSL_CW:
20573 if (color_space == CSPACE_HSL_CW)
20574 direction = 1;
20575 [[fallthrough]];
20576 case CSPACE_HSL_CCW:
20577 if (color_space == CSPACE_HSL_CCW)
20578 direction = -1;
20579 [[fallthrough]];
20580 case CSPACE_HSL:
20581 {
20582 double convert_start[3];
20583 double convert_end[3];
20584 double convert_result[3];
20585 RGBTo(start, convert_start, color_space);
20586 RGBTo(end, convert_end, color_space);
20587 convert_result[0] = WrapLerp(convert_start[0], convert_end[0], percent, 0.0, 1.0, direction);
20588 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20589 convert_result[2] = zc::math::Lerp(convert_start[2], convert_end[2], percent);
20590 return RGBFrom(convert_result, color_space);
20591 }
20592 case CSPACE_LAB:
20593 {
20594 double convert_start[3];
20595 double convert_end[3];
20596 double convert_result[3];
20597 RGBTo(start, convert_start, color_space);
20598 RGBTo(end, convert_end, color_space);
20599 convert_result[0] = zc::math::Lerp(convert_start[0], convert_end[0], percent);
20600 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20601 convert_result[2] = zc::math::Lerp(convert_start[2], convert_end[2], percent);
20602 return RGBFrom(convert_result, color_space);
20603 }
20604 case CSPACE_LCH_CW:
20605 if (color_space == CSPACE_LCH_CW)
20606 direction = 1;
20607 [[fallthrough]];
20608 case CSPACE_LCH_CCW:
20609 if (color_space == CSPACE_LCH_CCW)
20610 direction = -1;
20611 [[fallthrough]];
20612 case CSPACE_LCH:
20613 {
20614 double convert_start[3];
20615 double convert_end[3];
20616 double convert_result[3];
20617 RGBTo(start, convert_start, color_space);
20618 RGBTo(end, convert_end, color_space);
20619 convert_result[0] = zc::math::Lerp(convert_start[0], convert_end[0], percent);
20620 convert_result[1] = zc::math::Lerp(convert_start[1], convert_end[1], percent);
20621 convert_result[2] = WrapLerp(convert_start[2], convert_end[2], percent, 0.0, 360.0, direction);
20622 return RGBFrom(convert_result, color_space);
20623 }
20624 }
20625 return start;
20626 139696 }
20627
20628 void user_paldata::RGBTo(RGB c, double arr[], int32_t color_space)
20629 {
20630 //From easyrgb.com/en/math.php
20631 double upper = scripting_max_color_val;
20632 double r = vbound(c.r / upper, 0.0, 1.0);
20633 double g = vbound(c.g / upper, 0.0, 1.0);
20634 double b = vbound(c.b / upper, 0.0, 1.0);
20635 switch (color_space)
20636 {
20637 case CSPACE_CMYK:
20638 {
20639 double c = 1.0 - r;
20640 double m = 1.0 - g;
20641 double y = 1.0 - b;
20642
20643 double k = 1.0;
20644
20645 if (c < k) k = c;
20646 if (m < k) k = m;
20647 if (y < k) k = y;
20648 if (k == 1)
20649 {
20650 c = 0.0;
20651 m = 0.0;
20652 y = 0.0;
20653 }
20654 else
20655 {
20656 c = (c - k) / (1.0 - k);
20657 m = (m - k) / (1.0 - k);
20658 y = (y - k) / (1.0 - k);
20659 }
20660 arr[0] = c;
20661 arr[1] = m;
20662 arr[2] = y;
20663 arr[3] = k;
20664 break;
20665 }
20666 case CSPACE_HSV_CW:
20667 case CSPACE_HSV_CCW:
20668 case CSPACE_HSV:
20669 {
20670 double min_val = std::min(std::min(r, g), b);
20671 double max_val = std::max(std::max(r, g), b);
20672 double del_max = max_val - min_val;
20673
20674 double h = 0;
20675 double s = 0;
20676 double v = max_val;
20677
20678 if (del_max != 0) //Set chroma if not gray
20679 {
20680 s = del_max / max_val;
20681
20682 double del_r = (((max_val - r) / 6.0) + (del_max / 2.0)) / del_max;
20683 double del_g = (((max_val - g) / 6.0) + (del_max / 2.0)) / del_max;
20684 double del_b = (((max_val - b) / 6.0) + (del_max / 2.0)) / del_max;
20685
20686 if (r == max_val) h = del_b - del_g;
20687 else if (g == max_val) h = (1.0 / 3.0) + del_r - del_b;
20688 else if (b == max_val) h = (2.0 / 3.0) + del_g - del_r;
20689
20690 if (h < 0) ++h;
20691 if (h > 1) --h;
20692 }
20693
20694 arr[0] = h;
20695 arr[1] = s;
20696 arr[2] = v;
20697 break;
20698 }
20699 case CSPACE_HSL_CW:
20700 case CSPACE_HSL_CCW:
20701 case CSPACE_HSL:
20702 {
20703 double min_val = std::min(std::min(r, g), b);
20704 double max_val = std::max(std::max(r, g), b);
20705 double del_max = max_val - min_val;
20706
20707 double h = 0;
20708 double s = 0;
20709 double l = (max_val + min_val) / 2.0;
20710
20711 if (del_max != 0) //Set chroma if not gray
20712 {
20713 if (l < 0.5) s = del_max / (max_val + min_val);
20714 else s = del_max / (2 - max_val - min_val);
20715
20716 double del_r = (((max_val - r) / 6.0) + (del_max / 2.0)) / del_max;
20717 double del_g = (((max_val - g) / 6.0) + (del_max / 2.0)) / del_max;
20718 double del_b = (((max_val - b) / 6.0) + (del_max / 2.0)) / del_max;
20719
20720 if (r == max_val) h = del_b - del_g;
20721 else if (g == max_val) h = (1.0 / 3.0) + del_r - del_b;
20722 else if (b == max_val) h = (2.0 / 3.0) + del_g - del_r;
20723
20724 if (h < 0) ++h;
20725 if (h > 1) --h;
20726 }
20727
20728 arr[0] = h;
20729 arr[1] = s;
20730 arr[2] = l;
20731 break;
20732 }
20733 case CSPACE_LAB:
20734 {
20735 if (r > 0.04045) r = pow(((r + 0.055) / 1.055), 2.4);
20736 else r /= 12.92;
20737 if (g > 0.04045) g = pow(((g + 0.055) / 1.055), 2.4);
20738 else g /= 12.92;
20739 if (b > 0.04045) b = pow(((b + 0.055) / 1.055), 2.4);
20740 else b /= 12.92;
20741
20742 double x = r * 0.4124 + g * 0.3576 + b * 0.1805;
20743 double y = r * 0.2126 + g * 0.7152 + b * 0.0722;
20744 double z = r * 0.0193 + g * 0.1192 + b * 0.9505;
20745
20746 if (x > 0.008856) x = pow(x, 1.0 / 3.0);
20747 else x = (7.787 * x) + (16.0 / 116.0);
20748 if (y > 0.008856) y = pow(y, 1.0 / 3.0);
20749 else y = (7.787 * y) + (16.0 / 116.0);
20750 if (z > 0.008856) z = pow(z, 1.0 / 3.0);
20751 else z = (7.787 * z) + (16.0 / 116.0);
20752
20753 double CIEL = (116 * y) - 16;
20754 double CIEa = 500 * (x - y);
20755 double CIEb = 200 * (y - z);
20756
20757 arr[0] = CIEL;
20758 arr[1] = CIEa;
20759 arr[2] = CIEb;
20760 break;
20761 }
20762 case CSPACE_LCH_CW:
20763 case CSPACE_LCH_CCW:
20764 case CSPACE_LCH:
20765 {
20766 if (r > 0.04045) r = pow(((r + 0.055) / 1.055), 2.4);
20767 else r /= 12.92;
20768 if (g > 0.04045) g = pow(((g + 0.055) / 1.055), 2.4);
20769 else g /= 12.92;
20770 if (b > 0.04045) b = pow(((b + 0.055) / 1.055), 2.4);
20771 else b /= 12.92;
20772
20773 double x = r * 0.4124 + g * 0.3576 + b * 0.1805;
20774 double y = r * 0.2126 + g * 0.7152 + b * 0.0722;
20775 double z = r * 0.0193 + g * 0.1192 + b * 0.9505;
20776
20777 if (x > 0.008856) x = pow(x, 1.0 / 3.0);
20778 else x = (7.787 * x) + (16.0 / 116.0);
20779 if (y > 0.008856) y = pow(y, 1.0 / 3.0);
20780 else y = (7.787 * y) + (16.0 / 116.0);
20781 if (z > 0.008856) z = pow(z, 1.0 / 3.0);
20782 else z = (7.787 * z) + (16.0 / 116.0);
20783
20784 double CIEL = (116 * y) - 16;
20785 double CIEa = 500 * (x - y);
20786 double CIEb = 200 * (y - z);
20787
20788 double h = atan2(CIEb, CIEa);
20789 if (h > 0) h = (h / PI) * 180;
20790 else h = 360 - (abs(h) / PI) * 180;
20791
20792 double CIEC = sqrt(pow(CIEa, 2) + pow(CIEb, 2));
20793
20794 arr[0] = CIEL;
20795 arr[1] = CIEC;
20796 arr[2] = h;
20797 break;
20798 }
20799 }
20800
20801 }
20802
20803 RGB user_paldata::RGBFrom(double arr[], int32_t color_space)
20804 {
20805 double upper = scripting_max_color_val;
20806 double r = 0.0;
20807 double g = 0.0;
20808 double b = 0.0;
20809 switch (color_space)
20810 {
20811 case CSPACE_CMYK:
20812 {
20813 double c = (arr[0] * (1 - arr[3]) + arr[3]);
20814 double m = (arr[1] * (1 - arr[3]) + arr[3]);
20815 double y = (arr[2] * (1 - arr[3]) + arr[3]);
20816
20817 r = vbound((1 - c) * upper, 0.0, upper);
20818 g = vbound((1 - m) * upper, 0.0, upper);
20819 b = vbound((1 - y) * upper, 0.0, upper);
20820 return _RGB(r, g, b);
20821 break;
20822 }
20823 case CSPACE_HSV_CW:
20824 case CSPACE_HSV_CCW:
20825 case CSPACE_HSV:
20826 {
20827 double h = arr[0];
20828 double s = arr[1];
20829 double v = arr[2];
20830
20831 if (s == 0)
20832 {
20833 r = v;
20834 g = v;
20835 b = v;
20836 }
20837 else
20838 {
20839 double var_h = h * 6;
20840 if (var_h >= 6) var_h = 0;
20841 int32_t var_i = floor(var_h);
20842 double var_1 = v * (1 - s);
20843 double var_2 = v * (1 - s * (var_h - var_i));
20844 double var_3 = v * (1 - s * (1 - (var_h - var_i)));
20845
20846 switch (var_i)
20847 {
20848 case 0:
20849 r = v;
20850 g = var_3;
20851 b = var_1;
20852 break;
20853 case 1:
20854 r = var_2;
20855 g = v;
20856 b = var_1;
20857 break;
20858 case 2:
20859 r = var_1;
20860 g = v;
20861 b = var_3;
20862 break;
20863 case 3:
20864 r = var_1;
20865 g = var_2;
20866 b = v;
20867 break;
20868 case 4:
20869 r = var_3;
20870 g = var_1;
20871 b = v;
20872 break;
20873 default:
20874 r = v;
20875 g = var_1;
20876 b = var_2;
20877 }
20878 }
20879
20880 r = vbound(r * upper, 0.0, upper);
20881 g = vbound(g * upper, 0.0, upper);
20882 b = vbound(b * upper, 0.0, upper);
20883
20884 return _RGB(r, g, b);
20885 }
20886 case CSPACE_HSL_CW:
20887 case CSPACE_HSL_CCW:
20888 case CSPACE_HSL:
20889 {
20890 double h = arr[0];
20891 double s = arr[1];
20892 double l = arr[2];
20893
20894 if (s == 0)
20895 {
20896 r = l;
20897 g = l;
20898 b = l;
20899 }
20900 else
20901 {
20902 double var_1;
20903 double var_2;
20904 if (l < 0.5)var_2 = l * (1 + s);
20905 else var_2 = (l + s) - (s * l);
20906
20907 var_1 = 2 * l - var_2;
20908
20909 r = HueToRGB(var_1, var_2, h + (1.0 / 3.0));
20910 g = HueToRGB(var_1, var_2, h);
20911 b = HueToRGB(var_1, var_2, h - (1.0 / 3.0));
20912 }
20913
20914 r = vbound(r * upper, 0.0, upper);
20915 g = vbound(g * upper, 0.0, upper);
20916 b = vbound(b * upper, 0.0, upper);
20917
20918 return _RGB(r, g, b);
20919 }
20920 case CSPACE_LAB:
20921 {
20922 double CIEL = arr[0];
20923 double CIEa = arr[1];
20924 double CIEb = arr[2];
20925
20926 double var_y = (CIEL + 16) / 116.0;
20927 double var_x = CIEa / 500.0 + var_y;
20928 double var_z = var_y - CIEb / 200.0;
20929
20930 if (pow(var_x, 3) > 0.008856) var_x = pow(var_x, 3);
20931 else var_x = (var_x - 16.0 / 116.0) / 7.787;
20932 if (pow(var_y, 3) > 0.008856) var_y = pow(var_y, 3);
20933 else var_y = (var_y - 16.0 / 116.0) / 7.787;
20934 if (pow(var_z, 3) > 0.008856) var_z = pow(var_z, 3);
20935 else var_z = (var_z - 16.0 / 116.0) / 7.787;
20936
20937 r = var_x * 3.2406 + var_y * -1.5372 + var_z * -0.4986;
20938 g = var_x * -0.9689 + var_y * 1.8758 + var_z * 0.0415;
20939 b = var_x * 0.0557 + var_y * -0.2040 + var_z * 1.0570;
20940
20941 if (r > 0.0031308) r = 1.055 * pow(r, (1 / 2.4)) - 0.055;
20942 else r = 12.92 * r;
20943 if (g > 0.0031308) g = 1.055 * pow(g, (1 / 2.4)) - 0.055;
20944 else g = 12.92 * g;
20945 if (b > 0.0031308) b = 1.055 * pow(b, (1 / 2.4)) - 0.055;
20946 else b = 12.92 * b;
20947
20948 r = vbound(r * upper, 0.0, upper);
20949 g = vbound(g * upper, 0.0, upper);
20950 b = vbound(b * upper, 0.0, upper);
20951
20952 return _RGB(r, g, b);
20953 }
20954 case CSPACE_LCH_CW:
20955 case CSPACE_LCH_CCW:
20956 case CSPACE_LCH:
20957 {
20958 double CIEL = arr[0];
20959 double CIEa = cos((arr[2] * PI) / 180.0) * arr[1];
20960 double CIEb = sin((arr[2] * PI) / 180.0) * arr[1];
20961
20962 double var_y = (CIEL + 16) / 116.0;
20963 double var_x = CIEa / 500.0 + var_y;
20964 double var_z = var_y - CIEb / 200.0;
20965
20966 if (pow(var_y, 3) > 0.008856) var_y = pow(var_y, 3);
20967 else var_y = (var_y - 16.0 / 116.0) / 7.787;
20968 if (pow(var_x, 3) > 0.008856) var_x = pow(var_x, 3);
20969 else var_x = (var_x - 16.0 / 116.0) / 7.787;
20970 if (pow(var_z, 3) > 0.008856) var_z = pow(var_z, 3);
20971 else var_z = (var_z - 16.0 / 116.0) / 7.787;
20972
20973 r = var_x * 3.2406 + var_y * -1.5372 + var_z * -0.4986;
20974 g = var_x * -0.9689 + var_y * 1.8758 + var_z * 0.0415;
20975 b = var_x * 0.0557 + var_y * -0.2040 + var_z * 1.0570;
20976
20977 if (r > 0.0031308) r = 1.055 * pow(r, (1 / 2.4)) - 0.055;
20978 else r = 12.92 * r;
20979 if (g > 0.0031308) g = 1.055 * pow(g, (1 / 2.4)) - 0.055;
20980 else g = 12.92 * g;
20981 if (b > 0.0031308) b = 1.055 * pow(b, (1 / 2.4)) - 0.055;
20982 else b = 12.92 * b;
20983
20984 r = vbound(r * upper, 0.0, upper);
20985 g = vbound(g * upper, 0.0, upper);
20986 b = vbound(b * upper, 0.0, upper);
20987
20988 return _RGB(r, g, b);
20989 }
20990 }
20991 return _RGB(0, 0, 0);
20992 }
20993 double user_paldata::HueToRGB(double v1, double v2, double vH)
20994 {
20995 if (vH < 0) vH += 1;
20996 if (vH > 1) vH -= 1;
20997 if ((6 * vH) < 1) return (v1 + (v2 - v1) * 6 * vH);
20998 if ((2 * vH) < 1) return (v2);
20999 if ((3 * vH) < 2) return (v1 + (v2 - v1) * ((2.0 / 3.0) - vH) * 6);
21000 return (v1);
21001 }
21002
21003 double user_paldata::WrapLerp(double a, double b, double t, double min, double max, int32_t direction)
21004 {
21005 double dif = abs(a - b);
21006 double range = abs(max - min);
21007
21008 switch (direction)
21009 {
21010 case 0:
21011 if (dif > range * 0.5)
21012 dif = range - dif;
21013 if (a + dif == b)
21014 direction = 1;
21015 else
21016 direction = -1;
21017 break;
21018 case 1:
21019 if (b < a)
21020 dif = range - dif;
21021 break;
21022 case -1:
21023 if (b > a)
21024 dif = range - dif;
21025 break;
21026 }
21027
21028 double ret = zc::math::Lerp(a, a + dif * direction, t);
21029
21030 if (ret <= min)
21031 ret += range;
21032 else if (ret >= max)
21033 ret -= range;
21034 return ret;
21035 }
21036
21037 //Mixes an entire palette given two paldatas
21038 5231 void user_paldata::mix(user_paldata *pal_start, user_paldata *pal_end, double percent, int32_t color_space, int32_t start_color, int32_t end_color)
21039 {
21040
2/2
✓ Branch 0 taken 184496 times.
✓ Branch 1 taken 5231 times.
189727 for (int32_t q = start_color; q < end_color; ++q)
21041 {
21042
3/4
✓ Branch 0 taken 139696 times.
✓ Branch 1 taken 44800 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 139696 times.
184496 if (get_bit(pal_start->colors_used, q) && get_bit(pal_end->colors_used, q)) {
21043 139696 RGB start = pal_start->colors[q];
21044 139696 RGB end = pal_end->colors[q];
21045 139696 colors[q] = mix_color(start, end, percent, color_space);
21046 139696 set_bit(colors_used, q, true);
21047 139696 }
21048 184496 }
21049 5231 }
21050
21051 53 void item_display_name(const bool setter)
21052 {
21053 53 int32_t ID = GET_REF(itemdataref);
21054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
53 if(unsigned(ID) >= MAXITEMS)
21055 return;
21056 53 int32_t arrayptr = get_register(sarg1);
21057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
53 if(setter)
21058 {
21059 std::string str;
21060 ArrayH::getString(arrayptr, str, 255);
21061 strcpy(itemsbuf[ID].display_name, str.c_str());
21062 }
21063 else
21064 {
21065
3/6
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
53 if(ArrayH::setArray(arrayptr, string(itemsbuf[ID].display_name)) == SH::_Overflow)
21066 Z_scripterrlog("Array supplied to 'itemdata->GetDisplayName()' not large enough\n");
21067 }
21068 53 }
21069 void item_shown_name()
21070 {
21071 int32_t ID = GET_REF(itemdataref);
21072 if(unsigned(ID) >= MAXITEMS)
21073 return;
21074 int32_t arrayptr = get_register(sarg1);
21075 if(ArrayH::setArray(arrayptr, itemsbuf[ID].get_name()) == SH::_Overflow)
21076 Z_scripterrlog("Array supplied to 'itemdata->GetShownName()' not large enough\n");
21077 }
21078
21079 void FFScript::do_getDMapData_dmapname(const bool v)
21080 {
21081 int32_t ID = GET_REF(dmapdataref);
21082 int32_t arrayptr = get_register(sarg1);
21083
21084 if(BC::checkDMapID(ID) != SH::_NoError)
21085 return;
21086
21087 if(ArrayH::setArray(arrayptr, string(DMaps[ID].name)) == SH::_Overflow)
21088 Z_scripterrlog("Array supplied to 'dmapdata->GetName()' not large enough\n");
21089 }
21090
21091 void FFScript::do_setDMapData_dmapname(const bool v)
21092 {
21093 int32_t ID = GET_REF(dmapdataref);
21094 int32_t arrayptr = get_register(sarg1);
21095
21096 string filename_str;
21097
21098 if(BC::checkDMapID(ID) != SH::_NoError)
21099 return;
21100
21101
21102 ArrayH::getString(arrayptr, filename_str, 22);
21103 strncpy(DMaps[ID].name, filename_str.c_str(), 21);
21104 DMaps[ID].name[20]='\0';
21105 }
21106
21107 void FFScript::do_getDMapData_dmaptitle(const bool v)
21108 {
21109 int32_t ID = GET_REF(dmapdataref);
21110 int32_t arrayptr = get_register(sarg1);
21111
21112 if(BC::checkDMapID(ID) != SH::_NoError)
21113 return;
21114
21115 if (!get_qr(qr_OLD_DMAP_INTRO_STRINGS))
21116 {
21117 ArrayManager am(arrayptr);
21118 am.resize(DMaps[ID].title.size() + 1);
21119 }
21120 if(ArrayH::setArray(arrayptr, string(DMaps[ID].title)) == SH::_Overflow)
21121 Z_scripterrlog("Array supplied to 'dmapdata->GetTitle()' not large enough\n");
21122 }
21123
21124 void FFScript::do_setDMapData_dmaptitle(const bool v)
21125 {
21126 int32_t ID = GET_REF(dmapdataref);
21127 int32_t arrayptr = get_register(sarg1);
21128 string filename_str;
21129
21130 if(BC::checkDMapID(ID) != SH::_NoError)
21131 return;
21132
21133 if (get_qr(qr_OLD_DMAP_INTRO_STRINGS))
21134 {
21135 char namestr[21];
21136 ArrayH::getString(arrayptr, filename_str, 21);
21137 strncpy(namestr, filename_str.c_str(), 20);
21138 namestr[20] = '\0';
21139 DMaps[ID].title.assign(namestr);
21140 }
21141 else
21142 {
21143 ArrayH::getString(arrayptr, filename_str, ArrayH::getSize(arrayptr));
21144 DMaps[ID].title = filename_str;
21145 }
21146 }
21147
21148 void FFScript::do_getDMapData_dmapintro(const bool v)
21149 {
21150 int32_t ID = GET_REF(dmapdataref);
21151 int32_t arrayptr = get_register(sarg1);
21152
21153 if(BC::checkDMapID(ID) != SH::_NoError)
21154 return;
21155
21156 if(ArrayH::setArray(arrayptr, string(DMaps[ID].intro)) == SH::_Overflow)
21157 Z_scripterrlog("Array supplied to 'dmapdata->GetIntro()' not large enough\n");
21158 }
21159
21160 void FFScript::do_setDMapData_dmapintro(const bool v)
21161 {
21162 int32_t ID = GET_REF(dmapdataref);
21163 int32_t arrayptr = get_register(sarg1);
21164 string filename_str;
21165
21166 if(BC::checkDMapID(ID) != SH::_NoError)
21167 return;
21168
21169
21170 ArrayH::getString(arrayptr, filename_str, 73);
21171 strncpy(DMaps[ID].intro, filename_str.c_str(), 72);
21172 DMaps[ID].intro[72]='\0';
21173 }
21174
21175 14 void FFScript::do_getDMapData_music(const bool v)
21176 {
21177 14 int32_t ID = GET_REF(dmapdataref);
21178 14 int32_t arrayptr = get_register(sarg1);
21179
21180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if(BC::checkDMapID(ID) != SH::_NoError)
21181 return;
21182
21183
3/6
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 if(ArrayH::setArray(arrayptr, string(DMaps[ID].tmusic)) == SH::_Overflow)
21184 Z_scripterrlog("Array supplied to 'dmapdata->GetMusic()' not large enough\n");
21185 14 }
21186
21187 void FFScript::do_setDMapData_music(const bool v)
21188 {
21189 int32_t ID = GET_REF(dmapdataref);
21190 int32_t arrayptr = get_register(sarg1);
21191 string filename_str;
21192
21193 if(BC::checkDMapID(ID) != SH::_NoError)
21194 return;
21195
21196
21197 ArrayH::getString(arrayptr, filename_str, 56);
21198 strncpy(DMaps[ID].tmusic, filename_str.c_str(), 55);
21199 DMaps[ID].tmusic[55]='\0';
21200 }
21201
21202 6366 void FFScript::do_loadnpcdata(const bool v)
21203 {
21204 6366 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21205
21206
2/4
✓ Branch 0 taken 6366 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6366 times.
6366 if ( ID < 1 || ID > (MAXGUYS-1) )
21207 {
21208 Z_scripterrlog("Invalid NPC ID passed to Game->LoadNPCData: %d\n", ID);
21209 ri->npcdataref = MAX_DWORD;
21210 }
21211
21212 6366 else ri->npcdataref = ID;
21213 6366 }
21214 54 void FFScript::do_loadmessagedata(const bool v)
21215 {
21216 54 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21217
21218
2/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
54 if ( ID < 1 || ID > (msg_count-1) )
21219 {
21220 Z_scripterrlog("Invalid Message ID passed to Game->LoadMessageData: %d\n", ID);
21221 ri->msgdataref = MAX_DWORD;
21222 }
21223
21224 54 else ri->msgdataref = ID;
21225 54 }
21226 //same syntax as loadmessage data
21227 //the input is an array
21228 52 void FFScript::do_messagedata_setstring(const bool v)
21229 {
21230 52 int32_t arrayptr = get_register(sarg1);
21231 52 int32_t ID = GET_REF(msgdataref);
21232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if(BC::checkMessage(ID) != SH::_NoError)
21233 return;
21234
21235 52 std::string s;
21236
1/2
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
52 ArrayH::getString(arrayptr, s, MSG_NEW_SIZE);
21237
21238 52 auto encoding_type = get_qr(qr_OLD_SCRIPTS_MESSAGE_DATA_BINARY_ENCODING) ?
21239 MsgStr::EncodingType::Binary :
21240 MsgStr::EncodingType::Ascii;
21241
2/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
52 MsgStrings[ID].set(s, encoding_type);
21242 52 }
21243 18 void FFScript::do_messagedata_getstring(const bool v)
21244 {
21245 18 int32_t ID = GET_REF(msgdataref);
21246 18 int32_t arrayptr = get_register(sarg1);
21247
21248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 if(BC::checkMessage(ID) != SH::_NoError)
21249 return;
21250
21251
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
18 if (get_qr(qr_OLD_SCRIPTS_MESSAGE_DATA_BINARY_ENCODING))
21252 14 MsgStrings[ID].ensureLegacyEncoding();
21253 else
21254 4 MsgStrings[ID].ensureAsciiEncoding();
21255
21256
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if(ArrayH::setArray(arrayptr, MsgStrings[ID].s, true) == SH::_Overflow)
21257 Z_scripterrlog("Array supplied to 'messagedata->Get()' not large enough\n");
21258 18 }
21259
21260 6042586 void FFScript::do_loadcombodata(const bool v)
21261 {
21262 6042586 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21263
21264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6042586 times.
6042586 if ( (unsigned)ID > (MAXCOMBOS-1) )
21265 {
21266 scripting_log_error_with_context("Invalid combodata ID: {}", GET_REF(combodataref));
21267 ri->combodataref = 0;
21268 }
21269
21270 6042586 else ri->combodataref = ID;
21271 6042586 }
21272
21273 3585254 void FFScript::do_loadmapdata_tempscr(const bool v)
21274 {
21275 3585254 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21276
21277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3585254 times.
3585254 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21278 {
21279 ri->mapdataref = 0;
21280 set_register(sarg1, ri->mapdataref);
21281 return;
21282 }
21283
21284 3585254 ri->mapdataref = create_mapdata_temp_ref(mapdata_type::TemporaryCurrentRegion, cur_screen, layer);
21285 3585254 set_register(sarg1, ri->mapdataref);
21286 3585254 }
21287
21288 void FFScript::do_loadmapdata_tempscr2(const bool v)
21289 {
21290 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21291 int32_t screen = SH::get_arg(sarg2, v) / 10000;
21292
21293 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21294 {
21295 ri->mapdataref = 0;
21296 set_register(sarg1, ri->mapdataref);
21297 return;
21298 }
21299
21300 if (!is_in_current_region(screen))
21301 {
21302 scripting_log_error_with_context("Must use a screen in the current region. got: {}", screen);
21303 ri->mapdataref = 0;
21304 set_register(sarg1, ri->mapdataref);
21305 return;
21306 }
21307
21308 ri->mapdataref = create_mapdata_temp_ref(mapdata_type::TemporaryCurrentScreen, screen, layer);
21309 set_register(sarg1, ri->mapdataref);
21310 }
21311
21312 static void do_loadtmpscrforcombopos(const bool v)
21313 {
21314 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21315 rpos_t rpos = (rpos_t)(SH::get_arg(sarg2, v) / 10000);
21316
21317 if (BC::checkBoundsRpos(rpos, (rpos_t)0, region_max_rpos) != SH::_NoError)
21318 {
21319 ri->mapdataref = 0;
21320 set_register(sarg1, ri->mapdataref);
21321 return;
21322 }
21323 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21324 {
21325 ri->mapdataref = 0;
21326 set_register(sarg1, ri->mapdataref);
21327 return;
21328 }
21329
21330 set_register(sarg1, create_mapdata_temp_ref(mapdata_type::TemporaryCurrentScreen, get_screen_for_rpos(rpos), layer));
21331 }
21332
21333 182518 void FFScript::do_loadmapdata_scrollscr(const bool v)
21334 {
21335 182518 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21336
21337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 182518 times.
182518 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21338 {
21339 ri->mapdataref = 0;
21340 set_register(sarg1, ri->mapdataref);
21341 return;
21342 }
21343
21344 182518 ri->mapdataref = create_mapdata_temp_ref(mapdata_type::TemporaryScrollingRegion, scrolling_hero_screen, layer);
21345 182518 set_register(sarg1, ri->mapdataref);
21346 182518 }
21347
21348 void FFScript::do_loadmapdata_scrollscr2(const bool v)
21349 {
21350 int32_t layer = SH::get_arg(sarg1, v) / 10000;
21351 int32_t screen = SH::get_arg(sarg2, v) / 10000;
21352
21353 if (BC::checkBounds(layer, 0, 6) != SH::_NoError)
21354 {
21355 ri->mapdataref = 0;
21356 set_register(sarg1, ri->mapdataref);
21357 return;
21358 }
21359
21360 if (!is_in_screenscrolling_region(screen))
21361 {
21362 scripting_log_error_with_context("Must use a screen in the current scrolling region. got: {}", screen);
21363 ri->mapdataref = 0;
21364 set_register(sarg1, ri->mapdataref);
21365 return;
21366 }
21367
21368 ri->mapdataref = create_mapdata_temp_ref(mapdata_type::TemporaryScrollingScreen, screen, layer);
21369 set_register(sarg1, ri->mapdataref);
21370 }
21371
21372 void FFScript::do_loadshopdata(const bool v)
21373 {
21374 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21375
21376 if ( (unsigned)ID > 255 )
21377 {
21378 Z_scripterrlog("Invalid Shop ID passed to Game->LoadShopData: %d\n", ID);
21379 ri->shopdataref = 0;
21380 }
21381 else ri->shopdataref = ID;
21382 }
21383
21384
21385 void FFScript::do_loadinfoshopdata(const bool v)
21386 {
21387 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21388
21389 if ( (unsigned)ID > 255 )
21390 {
21391 Z_scripterrlog("Invalid Shop ID passed to Game->LoadShopData: %d\n", ID);
21392 ri->shopdataref = 0;
21393 }
21394 else ri->shopdataref = ID+NUMSHOPS;
21395 }
21396
21397 5603 void FFScript::do_loadspritedata(const bool v)
21398 {
21399 5603 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21400
21401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5603 times.
5603 if ( (unsigned)ID > (MAXWPNS-1) )
21402 {
21403 Z_scripterrlog("Invalid Sprite ID passed to Game->LoadSpriteData: %d\n", ID);
21404 ri->spritedataref = 0;
21405 }
21406
21407 5603 else ri->spritedataref = ID;
21408 5603 }
21409
21410 10 void FFScript::do_loadbitmapid(const bool v)
21411 {
21412 10 int32_t ID = SH::get_arg(sarg1, v) / 10000;
21413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 switch(ID)
21414 {
21415 case rtSCREEN:
21416 case rtBMP0:
21417 case rtBMP1:
21418 case rtBMP2:
21419 case rtBMP3:
21420 case rtBMP4:
21421 case rtBMP5:
21422 case rtBMP6:
21423 10 ri->bitmapref = ID+10; break;
21424 default:
21425 {
21426 Z_scripterrlog("Invalid Bitmap ID passed to Game->Load BitmapID: %d\n", ID);
21427 ri->bitmapref = 0; break;
21428 }
21429 }
21430 10 }
21431
21432 166704 void do_createlweapon(const bool v)
21433 {
21434 166704 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21435
21436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 166704 times.
166704 if(BC::checkWeaponID(ID) != SH::_NoError)
21437 return;
21438
21439
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 if ( Lwpns.has_space() )
21440 {
21441 166704 (void)Lwpns.add
21442 (
21443
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
333408 new weapon
21444 (
21445
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 (zfix)0, /*X*/
21446
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 (zfix)0, /*Y*/
21447
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 (zfix)0, /*Z*/
21448 166704 ID, /*id*/
21449 0, /*type*/
21450 0, /*power*/
21451 0, /*dir*/
21452 -1, /*Parentid*/
21453
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 Hero.getUID(), /*prntid*/
21454 false, /*isdummy*/
21455 1, /*script_gen*/
21456 1, /*islwpn*/
21457 166704 (ID==wWind?1:0) /*special*/
21458 )
21459 );
21460 166704 ri->lwpnref = Lwpns.spr(Lwpns.Count() - 1)->getUID();
21461 166704 weapon *w = (weapon*)Lwpns.spr(Lwpns.Count()-1); //last created
21462 166704 w->screen_spawned = ri->screenref;
21463 166704 w->ScriptGenerated = 1;
21464 166704 w->isLWeapon = 1;
21465
1/2
✓ Branch 0 taken 166704 times.
✗ Branch 1 not taken.
166704 if(ID == wWind) w->specialinfo = 1;
21466 166704 Z_eventlog("Script created lweapon %d with UID = %u\n", ID, ri->lwpnref);
21467 166704 }
21468 else
21469 {
21470 ri->lwpnref = 0; // Now NULL
21471 Z_scripterrlog("Couldn't create lweapon %d, screen lweapon limit reached\n", ID);
21472 }
21473 166704 }
21474
21475 303017 void do_createeweapon(const bool v)
21476 {
21477 303017 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21478
21479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 303017 times.
303017 if(BC::checkWeaponID(ID) != SH::_NoError)
21480 return;
21481
21482
1/2
✓ Branch 0 taken 303017 times.
✗ Branch 1 not taken.
303017 if ( Ewpns.has_space() )
21483 {
21484 303017 addEwpn(0, 0, 0, ID, 0, 0, 0, -1,1); //Param 9 marks it as script-generated.
21485
4/6
✓ Branch 0 taken 242350 times.
✓ Branch 1 taken 60667 times.
✓ Branch 2 taken 242350 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 242350 times.
✗ Branch 5 not taken.
303017 if( ID > wEnemyWeapons || ( ID >= wScript1 && ID <= wScript10) )
21486 {
21487 303017 weapon *w = (weapon*)Ewpns.spr(Ewpns.Count()-1); //last created
21488 303017 w->screen_spawned = ri->screenref;
21489 303017 w->ScriptGenerated = 1;
21490 303017 w->isLWeapon = 0;
21491 303017 ri->ewpnref = Ewpns.spr(Ewpns.Count() - 1)->getUID();
21492 303017 Z_eventlog("Script created eweapon %d with UID = %u\n", ID, ri->ewpnref);
21493 303017 }
21494 else
21495 {
21496 Z_scripterrlog("Couldn't create eweapon: Invalid ID/Type (%d) specified.\n", ID);
21497 return;
21498 }
21499 303017 }
21500 else
21501 {
21502 ri->ewpnref = 0;
21503 Z_scripterrlog("Couldn't create eweapon %d, screen eweapon limit reached\n", ID);
21504 }
21505 303017 }
21506
21507 22558 void do_createitem(const bool v)
21508 {
21509 22558 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21510
21511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22558 times.
22558 if(BC::checkItemID(ID) != SH::_NoError)
21512 return;
21513
21514
1/2
✓ Branch 0 taken 22558 times.
✗ Branch 1 not taken.
22558 if ( items.has_space() )
21515 {
21516 22558 additem(0, (get_qr(qr_NOITEMOFFSET) ? 1: 0), ID, ipBIGRANGE);
21517 22558 sprite* item = items.spr(items.Count() - 1);
21518 22558 item->screen_spawned = ri->screenref;
21519 22558 ri->itemref = item->getUID();
21520 22558 Z_eventlog("Script created item \"%s\" with UID = %u\n", item_string[ID], ri->itemref);
21521 22558 }
21522 else
21523 {
21524 ri->itemref = 0;
21525 Z_scripterrlog("Couldn't create item \"%s\", screen item limit reached\n", item_string[ID]);
21526 }
21527 22558 }
21528
21529 3593 void do_createnpc(const bool v)
21530 {
21531 3593 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21532
21533
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3593 times.
3593 if(BC::checkGuyID(ID) != SH::_NoError)
21534 return;
21535
21536 //If we make a segmented enemy there'll be more than one sprite created
21537 3593 word numcreated = addenemy(ri->screenref, 0, 0, ID, -10);
21538
21539
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3593 times.
3593 if(numcreated == 0)
21540 {
21541 ri->npcref = 0;
21542 Z_scripterrlog("Couldn't create NPC \"%s\", screen NPC limit reached\n", guy_string[ID]);
21543 }
21544 else
21545 {
21546 3593 word index = guys.Count() - numcreated; //Get the main enemy, not a segment
21547 3593 ri->npcref = guys.spr(index)->getUID();
21548
21549
2/2
✓ Branch 0 taken 3629 times.
✓ Branch 1 taken 3593 times.
7222 for(; index<guys.Count(); index++)
21550 3629 ((enemy*)guys.spr(index))->script_spawned=true;
21551
21552 3593 Z_eventlog("Script created NPC \"%s\" with UID = %u\n", guy_string[ID], ri->npcref);
21553 }
21554 3593 }
21555
21556 ///----------------------------------------------------------------------------------------------------//
21557 //Drawing & Sound
21558
21559 1351 void do_message(const bool v)
21560 {
21561 1351 const int32_t ID = SH::get_arg(sarg1, v) / 10000;
21562
21563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1351 times.
1351 if(BC::checkMessage(ID) != SH::_NoError)
21564 return;
21565
21566
2/2
✓ Branch 0 taken 302 times.
✓ Branch 1 taken 1049 times.
1351 if(ID == 0)
21567 {
21568 302 dismissmsg();
21569 302 msgfont = get_zc_font(font_zfont);
21570 302 blockpath = false;
21571 302 Hero.finishedmsg();
21572 302 }
21573 else
21574 1049 donewmsg(get_scr(GET_REF(screenref)), ID);
21575 1351 }
21576
21577 53481822 INLINE void set_drawing_command_args(const int32_t j, const word numargs)
21578 {
21579
1/2
✓ Branch 0 taken 53481822 times.
✗ Branch 1 not taken.
53481822 assert(numargs <= DRAWCMD_MAX_ARG_COUNT);
21580
2/2
✓ Branch 0 taken 428972008 times.
✓ Branch 1 taken 53481822 times.
482453830 for(int32_t k = 1; k <= numargs; k++)
21581 428972008 script_drawing_commands[j][k] = SH::read_stack(ri->sp + (numargs - k));
21582 53481822 }
21583
21584 65196620 INLINE void set_user_bitmap_command_args(const int32_t j, const word numargs)
21585 {
21586
1/2
✓ Branch 0 taken 65196620 times.
✗ Branch 1 not taken.
65196620 assert(numargs <= DRAWCMD_MAX_ARG_COUNT);
21587 //ri->bitmapref = SH::read_stack(ri->sp+numargs);
21588
2/2
✓ Branch 0 taken 403729369 times.
✓ Branch 1 taken 65196620 times.
468925989 for(int32_t k = 1; k <= numargs; k++)
21589 403729369 script_drawing_commands[j][k] = SH::read_stack(ri->sp + (numargs - k));
21590 65196620 }
21591
21592 108886790 static DrawOrigin get_draw_origin_for_screen_draw_command()
21593 {
21594 108886790 DrawOrigin draw_origin = ri->screen_draw_origin;
21595
21596
2/2
✓ Branch 0 taken 3074170 times.
✓ Branch 1 taken 105812620 times.
108886790 if (draw_origin == DrawOrigin::Default)
21597 {
21598
4/4
✓ Branch 0 taken 8256 times.
✓ Branch 1 taken 105804364 times.
✓ Branch 2 taken 100787434 times.
✓ Branch 3 taken 5016930 times.
105812620 bool in_scrolling_region = is_in_scrolling_region() || (screenscrolling && scrolling_region.screen_count > 1);
21599 105812620 draw_origin = in_scrolling_region ? DrawOrigin::Region : DrawOrigin::PlayingField;
21600 105812620 }
21601
2/2
✓ Branch 0 taken 46076 times.
✓ Branch 1 taken 108840714 times.
108886790 if (draw_origin == DrawOrigin::Region)
21602 {
21603
2/2
✓ Branch 0 taken 38992 times.
✓ Branch 1 taken 7084 times.
46076 if (scrolling_using_new_region_coords)
21604 7084 draw_origin = DrawOrigin::RegionScrollingNew;
21605 46076 }
21606
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 108839230 times.
108840714 else if (draw_origin == DrawOrigin::RegionScrollingOld)
21607 {
21608 1484 draw_origin = DrawOrigin::Region;
21609 1484 }
21610
2/2
✓ Branch 0 taken 108838242 times.
✓ Branch 1 taken 988 times.
108839230 else if (draw_origin == DrawOrigin::RegionScrollingNew)
21611 {
21612
1/2
✓ Branch 0 taken 988 times.
✗ Branch 1 not taken.
988 if (!screenscrolling)
21613 draw_origin = DrawOrigin::Region;
21614 988 }
21615
21616 108886790 return draw_origin;
21617 }
21618
21619 11401698 static DrawOrigin get_draw_origin_for_bitmap_draw_command()
21620 {
21621 11401698 return DrawOrigin::Screen;
21622 }
21623
21624 120288488 static std::pair<DrawOrigin, int> get_draw_origin_for_draw_command(bool is_screen_draw, int scripting_bitmap_id)
21625 {
21626
2/2
✓ Branch 0 taken 99185808 times.
✓ Branch 1 taken 21102680 times.
120288488 if (get_qr(qr_BROKEN_SCRIPTS_BITMAP_DRAW_ORIGIN))
21627 99185808 return {get_draw_origin_for_screen_draw_command(), ri->screen_draw_origin_target};
21628
21629 21102680 auto [bitmap_id, _] = resolveScriptingBitmapId(scripting_bitmap_id);
21630
21631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21102680 times.
21102680 if (FFCore.doesResolveToDeprecatedSystemBitmap(bitmap_id))
21632 return {DrawOrigin::Screen, 0};
21633
21634
2/2
✓ Branch 0 taken 9700982 times.
✓ Branch 1 taken 11401698 times.
21102680 if (FFCore.doesResolveToScreenBitmap(bitmap_id))
21635 9700982 return {get_draw_origin_for_screen_draw_command(), ri->screen_draw_origin_target};
21636
21637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11401698 times.
11401698 if (!is_screen_draw)
21638 11401698 return {get_draw_origin_for_bitmap_draw_command(), 0};
21639
21640 return {DrawOrigin::Screen, 0};
21641 120288488 }
21642
21643 118678442 static void do_drawing_command(int32_t script_command, bool is_screen_draw)
21644 {
21645
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 118678442 times.
118678442 if (FFCore.skipscriptdraws)
21646 return;
21647
21648 118678442 int32_t j = script_drawing_commands.GetNext();
21649
1/2
✓ Branch 0 taken 118678442 times.
✗ Branch 1 not taken.
118678442 if(j == -1) //out of drawing command space
21650 {
21651 Z_scripterrlog("Max draw primitive limit reached\n");
21652 return;
21653 }
21654
21655 118678442 script_drawing_commands[j] = {};
21656 118678442 script_drawing_commands[j][0] = script_command;
21657 118678442 script_drawing_commands[j][DRAWCMD_CURRENT_TARGET] = zscriptDrawingRenderTarget->GetCurrentRenderTarget();
21658
21659
39/80
✗ Branch 0 not taken.
✓ Branch 1 taken 3699 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7323 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3196522 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1096478 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1850 times.
✓ Branch 11 taken 2356839 times.
✓ Branch 12 taken 383247 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1080 times.
✓ Branch 18 taken 2178024 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 2714863 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 5169752 times.
✓ Branch 23 taken 28377891 times.
✓ Branch 24 taken 964155 times.
✓ Branch 25 taken 148476 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 9270 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 904749 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 4170317 times.
✓ Branch 32 taken 49606 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 1568537 times.
✓ Branch 36 taken 190166 times.
✓ Branch 37 taken 12431 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 1898473 times.
✓ Branch 40 taken 34749 times.
✓ Branch 41 taken 26757 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✓ Branch 45 taken 186027 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 502 times.
✓ Branch 48 taken 144 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 80910 times.
✓ Branch 51 taken 64479 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 11288 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 1802707 times.
✓ Branch 56 taken 39064775 times.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✓ Branch 59 taken 865 times.
✓ Branch 60 taken 45504 times.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✓ Branch 65 taken 143658 times.
✓ Branch 66 taken 1876122 times.
✓ Branch 67 taken 113653 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 19821648 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 906 times.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
118678442 switch(script_command)
21660 {
21661 case RECTR:
21662 3196522 set_drawing_command_args(j, 12);
21663 3196522 break;
21664
21665 case FRAMER:
21666 set_drawing_command_args(j, 9);
21667 break;
21668
21669 case CIRCLER:
21670 1096478 set_drawing_command_args(j, 11);
21671 1096478 break;
21672
21673 case ARCR:
21674 set_drawing_command_args(j, 14);
21675 break;
21676
21677 case ELLIPSER:
21678 1850 set_drawing_command_args(j, 12);
21679 1850 break;
21680
21681 case LINER:
21682 2356839 set_drawing_command_args(j, 11);
21683 2356839 break;
21684
21685 case PUTPIXELR:
21686 383247 set_drawing_command_args(j, 8);
21687 383247 break;
21688
21689 case PIXELARRAYR:
21690 {
21691 set_drawing_command_args(j, 5);
21692 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21693
21694 int32_t arrayptr = script_drawing_commands[j][2];
21695 if ( !arrayptr ) //Don't crash because of vector size.
21696 {
21697 Z_scripterrlog("Invalid array pointer %d passed to Screen->PutPixels(). Aborting.", arrayptr);
21698 break;
21699 }
21700 int32_t sz = ArrayH::getSize(arrayptr);
21701 if(sz <= 0)
21702 {
21703 script_drawing_commands.PopLast();
21704 return;
21705 }
21706 v->resize(sz, 0);
21707 int32_t* pos = &v->at(0);
21708
21709 ArrayH::getValues(script_drawing_commands[j][2], pos, sz);
21710 script_drawing_commands[j].SetVector(v);
21711 break;
21712 }
21713
21714 case TILEARRAYR:
21715 {
21716 set_drawing_command_args(j, 2);
21717 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21718
21719 int32_t arrayptr = script_drawing_commands[j][2];
21720 if ( !arrayptr ) //Don't crash because of vector size.
21721 {
21722 Z_scripterrlog("Invalid array pointer %d passed to Screen->DrawTiles(). Aborting.", arrayptr);
21723 break;
21724 }
21725 int32_t sz = ArrayH::getSize(arrayptr);
21726 if(sz <= 0)
21727 {
21728 script_drawing_commands.PopLast();
21729 return;
21730 }
21731 v->resize(sz, 0);
21732 int32_t* pos = &v->at(0);
21733
21734 ArrayH::getValues(script_drawing_commands[j][2], pos, sz);
21735 script_drawing_commands[j].SetVector(v);
21736 break;
21737 }
21738
21739 case LINESARRAY:
21740 {
21741 set_drawing_command_args(j, 2);
21742 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21743
21744 int32_t arrayptr = script_drawing_commands[j][2];
21745 if ( !arrayptr ) //Don't crash because of vector size.
21746 {
21747 Z_scripterrlog("Invalid array pointer %d passed to Screen->Lines(). Aborting.", arrayptr);
21748 break;
21749 }
21750 int32_t sz = ArrayH::getSize(arrayptr);
21751 if(sz <= 0)
21752 {
21753 script_drawing_commands.PopLast();
21754 return;
21755 }
21756 v->resize(sz, 0);
21757 int32_t* pos = &v->at(0);
21758
21759 ArrayH::getValues(script_drawing_commands[j][2], pos, sz);
21760 script_drawing_commands[j].SetVector(v);
21761 break;
21762 }
21763
21764 case COMBOARRAYR:
21765 {
21766 set_drawing_command_args(j, 2);
21767 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21768 int32_t arrayptr = script_drawing_commands[j][2];
21769 if ( !arrayptr ) //Don't crash because of vector size.
21770 {
21771 Z_scripterrlog("Invalid array pointer %d passed to Screen->DrawCombos(). Aborting.", arrayptr);
21772 break;
21773 }
21774 int32_t sz = ArrayH::getSize(arrayptr);
21775 if(sz <= 0)
21776 {
21777 script_drawing_commands.PopLast();
21778 return;
21779 }
21780 v->resize(sz, 0);
21781 int32_t* pos = &v->at(0);
21782
21783 ArrayH::getValues(script_drawing_commands[j][2], pos, sz);
21784 script_drawing_commands[j].SetVector(v);
21785 break;
21786 }
21787 case POLYGONR:
21788 {
21789 1080 set_drawing_command_args(j, 5);
21790
21791 1080 int32_t arrayptr = script_drawing_commands[j][3];
21792
1/2
✓ Branch 0 taken 1080 times.
✗ Branch 1 not taken.
1080 if ( !arrayptr ) //Don't crash because of vector size.
21793 {
21794 Z_scripterrlog("Invalid array pointer %d passed to Screen->Polygon(). Aborting.", arrayptr);
21795 break;
21796 }
21797 1080 int32_t sz = ArrayH::getSize(arrayptr);
21798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1080 times.
1080 if(sz <= 0)
21799 {
21800 script_drawing_commands.PopLast();
21801 return;
21802 }
21803
21804 1080 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21805 1080 v->resize(sz, 0);
21806
21807 1080 int32_t* pos = &v->at(0);
21808
21809
21810 1080 ArrayH::getValues(script_drawing_commands[j][3], pos, sz);
21811 1080 script_drawing_commands[j].SetVector(v);
21812 }
21813 1080 break;
21814
21815 case DRAWTILER:
21816 2178024 set_drawing_command_args(j, 15);
21817 2178024 break;
21818
21819 case DRAWTILECLOAKEDR:
21820 set_drawing_command_args(j, 7);
21821 break;
21822
21823 case DRAWCOMBOR:
21824 2714863 set_drawing_command_args(j, 16);
21825 2714863 break;
21826
21827 case DRAWCOMBOCLOAKEDR:
21828 set_drawing_command_args(j, 7);
21829 break;
21830
21831 case FASTTILER:
21832 5169752 set_drawing_command_args(j, 6);
21833 5169752 break;
21834
21835 case FASTCOMBOR:
21836 28377891 set_drawing_command_args(j, 6);
21837 28377891 break;
21838
21839 case DRAWCHARR:
21840 964155 set_drawing_command_args(j, 10);
21841 964155 break;
21842
21843 case DRAWINTR:
21844 148476 set_drawing_command_args(j, 11);
21845 148476 break;
21846
21847 case SPLINER:
21848 set_drawing_command_args(j, 11);
21849 break;
21850
21851 case QUADR:
21852 9270 set_drawing_command_args(j, 15);
21853 9270 break;
21854
21855 case TRIANGLER:
21856 set_drawing_command_args(j, 13);
21857 break;
21858
21859 case BITMAPR:
21860 904749 set_drawing_command_args(j, 12);
21861 904749 break;
21862
21863 case BITMAPEXR:
21864 set_drawing_command_args(j, 16);
21865 break;
21866
21867 case DRAWLAYERR:
21868 4170317 set_drawing_command_args(j, 8);
21869 4170317 break;
21870
21871 case DRAWSCREENR:
21872 49606 set_drawing_command_args(j, 6);
21873 49606 break;
21874
21875 case QUAD3DR:
21876 {
21877 set_drawing_command_args(j, 8);
21878 int32_t arrayptr = script_drawing_commands[j][2];
21879 int32_t sz = ArrayH::getSize(arrayptr);
21880 arrayptr = script_drawing_commands[j][3];
21881 sz += ArrayH::getSize(arrayptr);
21882 arrayptr = script_drawing_commands[j][4];
21883 sz += ArrayH::getSize(arrayptr);
21884 arrayptr = script_drawing_commands[j][5];
21885 sz += ArrayH::getSize(arrayptr);
21886 if(sz < 25)
21887 {
21888 script_drawing_commands.PopLast();
21889 return;
21890 }
21891 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21892 v->resize(sz, 0);
21893
21894 int32_t* pos = &v->at(0);
21895 int32_t* uv = &v->at(12);
21896 int32_t* col = &v->at(20);
21897 int32_t* size = &v->at(24);
21898
21899 ArrayH::getValues((script_drawing_commands[j][2]), pos, 12);
21900 ArrayH::getValues((script_drawing_commands[j][3]), uv, 8);
21901 ArrayH::getValues((script_drawing_commands[j][4]), col, 4);
21902 //FFCore.getValues2(script_drawing_commands[j][5], size, 2);
21903 ArrayH::getValues((script_drawing_commands[j][5]), size, 2);
21904
21905 script_drawing_commands[j].SetVector(v);
21906 }
21907 break;
21908
21909 case TRIANGLE3DR:
21910 {
21911 set_drawing_command_args(j, 8);
21912
21913 int32_t arrayptr = script_drawing_commands[j][2];
21914 int32_t sz = ArrayH::getSize(arrayptr);
21915 arrayptr = script_drawing_commands[j][3];
21916 sz += ArrayH::getSize(arrayptr);
21917 arrayptr = script_drawing_commands[j][4];
21918 sz += ArrayH::getSize(arrayptr);
21919 arrayptr = script_drawing_commands[j][5];
21920 sz += ArrayH::getSize(arrayptr);
21921 if(sz < 19)
21922 {
21923 script_drawing_commands.PopLast();
21924 return;
21925 }
21926
21927 std::vector<int32_t> *v = script_drawing_commands.GetVector();
21928 v->resize(sz, 0);
21929
21930 int32_t* pos = &v->at(0);
21931 int32_t* uv = &v->at(9);
21932 int32_t* col = &v->at(15);
21933 int32_t* size = &v->at(18);
21934
21935 ArrayH::getValues(script_drawing_commands[j][2], pos, 8);
21936 ArrayH::getValues(script_drawing_commands[j][3], uv, 6);
21937 ArrayH::getValues(script_drawing_commands[j][4], col, 3);
21938 ArrayH::getValues(script_drawing_commands[j][5], size, 2);
21939
21940 script_drawing_commands[j].SetVector(v);
21941 }
21942 break;
21943
21944 case DRAWSTRINGR:
21945 {
21946 1568537 set_drawing_command_args(j, 9);
21947 // Unused
21948 //const int32_t index = script_drawing_commands[j][19] = j;
21949
21950 1568537 string *str = script_drawing_commands.GetString();
21951 1568537 ArrayH::getString(script_drawing_commands[j][8], *str, 256);
21952 1568537 script_drawing_commands[j].SetString(str);
21953 }
21954 1568537 break;
21955
21956 case DRAWSTRINGR2:
21957 {
21958 190166 set_drawing_command_args(j, 11);
21959 // Unused
21960 //const int32_t index = script_drawing_commands[j][19] = j;
21961
21962 190166 string *str = script_drawing_commands.GetString();
21963 190166 ArrayH::getString(script_drawing_commands[j][8], *str, 256);
21964 190166 script_drawing_commands[j].SetString(str);
21965 }
21966 190166 break;
21967
21968 case BMPRECTR:
21969 12431 set_user_bitmap_command_args(j, 12); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+12);
21970 //Pop the args off the stack first. Then pop the pointer and push it to sdci[17].
21971 //The pointer for the bitmap variable (its literal value) is always ri->sp+numargs, so, with 12 args, it is sp+12.
21972 12431 break;
21973
21974 case BMPFRAMER:
21975 set_user_bitmap_command_args(j, 9);
21976 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9);
21977 break;
21978
21979 case CLEARBITMAP:
21980 {
21981 1898473 set_user_bitmap_command_args(j, 1);
21982 1898473 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+1);
21983 1898473 break;
21984 }
21985 case BITMAPCLEARTOCOLOR:
21986 {
21987 34749 set_user_bitmap_command_args(j, 2);
21988 34749 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+2);
21989 34749 break;
21990 }
21991 case REGENERATEBITMAP:
21992 {
21993 26757 set_user_bitmap_command_args(j, 3);
21994 26757 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+3);
21995 26757 break;
21996 }
21997 case BMPPOLYGONR:
21998 {
21999 set_user_bitmap_command_args(j, 5);
22000 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+5);
22001 int32_t arrayptr = script_drawing_commands[j][3];
22002 if ( !arrayptr ) //Don't crash because of vector size.
22003 {
22004 Z_scripterrlog("Invalid array pointer %d passed to Screen->Polygon(). Aborting.", arrayptr);
22005 break;
22006 }
22007 int32_t sz = ArrayH::getSize(arrayptr);
22008 if(sz <= 0)
22009 {
22010 script_drawing_commands.PopLast();
22011 return;
22012 }
22013 std::vector<int32_t> *v = script_drawing_commands.GetVector();
22014 v->resize(sz, 0);
22015
22016 int32_t* pos = &v->at(0);
22017
22018
22019 ArrayH::getValues(script_drawing_commands[j][3], pos, sz);
22020 script_drawing_commands[j].SetVector(v);
22021 }
22022 break;
22023 case READBITMAP:
22024 {
22025 set_user_bitmap_command_args(j, 2);
22026 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+2);
22027 string& user_path = *script_drawing_commands.GetString();
22028 ArrayH::getString(script_drawing_commands[j][2], user_path, 256);
22029
22030 if (get_qr(qr_BITMAP_AND_FILESYSTEM_PATHS_ALWAYS_RELATIVE))
22031 {
22032 if (auto r = parse_user_path(user_path, true); !r)
22033 {
22034 scripting_log_error_with_context("Error: {}", r.error());
22035 return;
22036 } else user_path = r.value();
22037 }
22038 else
22039 {
22040 regulate_path(user_path);
22041 }
22042
22043 script_drawing_commands[j].SetString(&user_path);
22044 break;
22045 }
22046 case WRITEBITMAP:
22047 {
22048 set_user_bitmap_command_args(j, 3);
22049 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+3);
22050 std::string& user_path = *script_drawing_commands.GetString();
22051 ArrayH::getString(script_drawing_commands[j][2], user_path, 256);
22052
22053 if (get_qr(qr_BITMAP_AND_FILESYSTEM_PATHS_ALWAYS_RELATIVE))
22054 {
22055 if (auto r = parse_user_path(user_path, true); !r)
22056 {
22057 scripting_log_error_with_context("Error: {}", r.error());
22058 return;
22059 } else user_path = r.value();
22060 }
22061 else
22062 {
22063 regulate_path(user_path);
22064 }
22065
22066 script_drawing_commands[j].SetString(&user_path);
22067 break;
22068 }
22069
22070 186027 case BMPCIRCLER: set_user_bitmap_command_args(j, 11); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11); break;
22071 case BMPARCR: set_user_bitmap_command_args(j, 14); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+14); break;
22072 502 case BMPELLIPSER: set_user_bitmap_command_args(j, 12); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+12); break;
22073 144 case BMPLINER: set_user_bitmap_command_args(j, 11); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11); break;
22074 case BMPSPLINER: set_user_bitmap_command_args(j, 11); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11); break;
22075 80910 case BMPPUTPIXELR: set_user_bitmap_command_args(j, 8); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+8); break;
22076 64479 case BMPDRAWTILER: set_user_bitmap_command_args(j, 15); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+15); break;
22077 case BMPDRAWTILECLOAKEDR: set_user_bitmap_command_args(j, 7); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+7); break;
22078 11288 case BMPDRAWCOMBOR: set_user_bitmap_command_args(j, 16); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+16); break;
22079 case BMPDRAWCOMBOCLOAKEDR: set_user_bitmap_command_args(j, 7); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+7); break;
22080 1802707 case BMPFASTTILER: set_user_bitmap_command_args(j, 6); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6); break;
22081 39064775 case BMPFASTCOMBOR: set_user_bitmap_command_args(j, 6); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6); break;
22082 case BMPDRAWCHARR: set_user_bitmap_command_args(j, 10); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+10); break;
22083 case BMPDRAWINTR: set_user_bitmap_command_args(j, 11); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11); break;
22084 case BMPDRAWSTRINGR:
22085 {
22086 865 set_user_bitmap_command_args(j, 9);
22087 865 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9);
22088 // Unused
22089 //const int32_t index = script_drawing_commands[j][19] = j;
22090
22091 865 string *str = script_drawing_commands.GetString();
22092 865 ArrayH::getString(script_drawing_commands[j][8], *str, 256);
22093 865 script_drawing_commands[j].SetString(str);
22094
22095 }
22096 865 break;
22097 case BMPDRAWSTRINGR2:
22098 {
22099 45504 set_user_bitmap_command_args(j, 11);
22100 45504 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+11);
22101 // Unused
22102 //const int32_t index = script_drawing_commands[j][19] = j;
22103
22104 45504 string *str = script_drawing_commands.GetString();
22105 45504 ArrayH::getString(script_drawing_commands[j][8], *str, 256);
22106 45504 script_drawing_commands[j].SetString(str);
22107
22108 }
22109 45504 break;
22110 case BMPQUADR: set_user_bitmap_command_args(j, 16); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+16); break;
22111 case BMPQUAD3DR:
22112 {
22113 set_drawing_command_args(j, 9);
22114 std::vector<int32_t> *v = script_drawing_commands.GetVector();
22115 v->resize(26, 0);
22116
22117 int32_t* pos = &v->at(0);
22118 int32_t* uv = &v->at(12);
22119 int32_t* col = &v->at(20);
22120 int32_t* size = &v->at(24);
22121
22122
22123 ArrayH::getValues(script_drawing_commands[j][2], pos, 12);
22124 ArrayH::getValues(script_drawing_commands[j][3], uv, 8);
22125 ArrayH::getValues(script_drawing_commands[j][4], col, 4);
22126 ArrayH::getValues(script_drawing_commands[j][5], size, 2);
22127
22128 script_drawing_commands[j].SetVector(v);
22129 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9);
22130
22131 }
22132 break;
22133 case BMPTRIANGLER: set_user_bitmap_command_args(j, 14); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+14); break;
22134 case BMPTRIANGLE3DR:
22135 {
22136 set_drawing_command_args(j, 9);
22137
22138 std::vector<int32_t> *v = script_drawing_commands.GetVector();
22139 v->resize(20, 0);
22140
22141 int32_t* pos = &v->at(0);
22142 int32_t* uv = &v->at(9);
22143 int32_t* col = &v->at(15);
22144 int32_t* size = &v->at(18);
22145
22146
22147 ArrayH::getValues(script_drawing_commands[j][2], pos, 8);
22148 ArrayH::getValues(script_drawing_commands[j][3], uv, 6);
22149 ArrayH::getValues(script_drawing_commands[j][4], col, 3);
22150 ArrayH::getValues(script_drawing_commands[j][5], size, 2);
22151
22152 script_drawing_commands[j].SetVector(v);
22153 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9);
22154 break;
22155 }
22156
22157 case BMPDRAWLAYERR:
22158 143658 set_user_bitmap_command_args(j, 8);
22159 143658 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+8);
22160 143658 break;
22161 case BMPDRAWLAYERSOLIDR:
22162 case BMPDRAWLAYERCFLAGR:
22163 case BMPDRAWLAYERCTYPER:
22164 case BMPDRAWLAYERCIFLAGR:
22165 case BMPDRAWLAYERSOLIDITYR: set_user_bitmap_command_args(j, 9); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+9); break;
22166 case BMPDRAWSCREENR:
22167 case BMPDRAWSCREENSOLIDR:
22168 case BMPDRAWSCREENSOLID2R:
22169 case BMPDRAWSCREENCOMBOFR:
22170 case BMPDRAWSCREENCOMBOIR:
22171 case BMPDRAWSCREENCOMBOTR:
22172 3699 set_user_bitmap_command_args(j, 6); script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6); break;
22173 case BMPBLIT:
22174 {
22175 1876122 set_user_bitmap_command_args(j, 16);
22176
22177 1876122 int bmp_target = SH::read_stack(ri->sp+16);
22178 1876122 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = bmp_target;
22179
22180
2/2
✓ Branch 0 taken 266080 times.
✓ Branch 1 taken 1610042 times.
1876122 if (!get_qr(qr_BROKEN_SCRIPTS_BITMAP_DRAW_ORIGIN))
22181 {
22182 1610042 int bmp_dest = script_drawing_commands[j][2];
22183 3220084 auto [draw_origin, draw_origin_target] = get_draw_origin_for_draw_command(is_screen_draw, bmp_dest);
22184 1610042 script_drawing_commands[j].secondary_draw_origin = draw_origin;
22185 1610042 script_drawing_commands[j].secondary_draw_origin_target = draw_origin_target;
22186 1610042 }
22187 1876122 break;
22188 }
22189 case BMPBLITTO:
22190 {
22191 113653 set_user_bitmap_command_args(j, 16);
22192 113653 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+16);
22193
22194
2/2
✓ Branch 0 taken 113649 times.
✓ Branch 1 taken 4 times.
113653 if (!get_qr(qr_BROKEN_SCRIPTS_BITMAP_DRAW_ORIGIN))
22195 {
22196 4 int bmp_source = script_drawing_commands[j][2];
22197 8 auto [draw_origin, draw_origin_target] = get_draw_origin_for_draw_command(is_screen_draw, bmp_source);
22198 4 script_drawing_commands[j].secondary_draw_origin = draw_origin;
22199 4 script_drawing_commands[j].secondary_draw_origin_target = draw_origin_target;
22200 4 }
22201 113653 break;
22202 }
22203 case TILEBLIT:
22204 {
22205 set_drawing_command_args(j, 17);
22206 break;
22207 }
22208 case COMBOBLIT:
22209 {
22210 set_drawing_command_args(j, 17);
22211 break;
22212 }
22213 case BMPTILEBLIT:
22214 {
22215 set_user_bitmap_command_args(j, 17);
22216 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+17);
22217 break;
22218 }
22219 case BMPCOMBOBLIT:
22220 {
22221 set_user_bitmap_command_args(j, 17);
22222 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+17);
22223 break;
22224 }
22225 case BMPMODE7:
22226 {
22227 set_user_bitmap_command_args(j, 13);
22228 //for(int32_t q = 0; q < 8; ++q )
22229 //Z_scripterrlog("FFscript blit() ri->d[%d] is: %d\n", q, ri->d[q]);
22230 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+13);
22231 break;
22232 }
22233
22234 case BMPWRITETILE:
22235 {
22236 19821648 set_user_bitmap_command_args(j, 6);
22237 19821648 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6);
22238 19821648 break;
22239 }
22240 case BMPDITHER:
22241 {
22242 set_user_bitmap_command_args(j, 5);
22243 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+5);
22244 break;
22245 }
22246 case BMPMASKDRAW:
22247 {
22248 906 set_user_bitmap_command_args(j, 3);
22249 906 script_drawing_commands[j][4] = 0x01 * 10000L;
22250 906 script_drawing_commands[j][5] = 0xFF * 10000L;
22251 906 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+3);
22252 906 break;
22253 }
22254 case BMPMASKDRAW2:
22255 {
22256 set_user_bitmap_command_args(j, 4);
22257 script_drawing_commands[j][5] = script_drawing_commands[j][4];
22258 script_drawing_commands[j][0] = BMPMASKDRAW;
22259 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+4);
22260 break;
22261 }
22262 case BMPMASKDRAW3:
22263 {
22264 set_user_bitmap_command_args(j, 5);
22265 script_drawing_commands[j][0] = BMPMASKDRAW;
22266 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+5);
22267 break;
22268 }
22269 case BMPMASKBLIT:
22270 {
22271 set_user_bitmap_command_args(j, 4);
22272 script_drawing_commands[j][5] = 0x01 * 10000L;
22273 script_drawing_commands[j][6] = 0xFF * 10000L;
22274 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+4);
22275 break;
22276 }
22277 case BMPMASKBLIT2:
22278 {
22279 set_user_bitmap_command_args(j, 5);
22280 script_drawing_commands[j][6] = script_drawing_commands[j][5];
22281 script_drawing_commands[j][0] = BMPMASKBLIT;
22282 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+5);
22283 break;
22284 }
22285 case BMPMASKBLIT3:
22286 {
22287 set_user_bitmap_command_args(j, 6);
22288 script_drawing_commands[j][0] = BMPMASKBLIT;
22289 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+6);
22290 break;
22291 }
22292 case BMPREPLCOLOR:
22293 case BMPSHIFTCOLOR:
22294 {
22295 7323 set_user_bitmap_command_args(j, 4);
22296 7323 script_drawing_commands[j][DRAWCMD_BMP_TARGET] = SH::read_stack(ri->sp+4);
22297 7323 break;
22298 }
22299
22300 case DRAWLIGHT_CONE:
22301 case DRAWLIGHT_CIRCLE:
22302 case DRAWLIGHT_SQUARE:
22303 {
22304 // These draw commands implicitly draw at the SPLAYER_DARKROOM_UNDER timing.
22305 // Shift the given args up by one.
22306 int num_args = script_command == DRAWLIGHT_CONE ? 8 : 7;
22307 set_drawing_command_args(j, num_args);
22308 for (int i = num_args; i >= 1; i--)
22309 script_drawing_commands[j][i + 1] = script_drawing_commands[j][i];
22310 script_drawing_commands[j][1] = SPLAYER_DARKROOM_UNDER * 10000;
22311 break;
22312 }
22313 }
22314
22315 int bmp_target;
22316
2/2
✓ Branch 0 taken 53527326 times.
✓ Branch 1 taken 65151116 times.
118678442 if (is_screen_draw)
22317 53527326 bmp_target = zscriptDrawingRenderTarget->GetCurrentRenderTarget() + 10;
22318 else
22319 65151116 bmp_target = script_drawing_commands[j][DRAWCMD_BMP_TARGET];
22320
22321 237356884 auto [draw_origin, draw_origin_target] = get_draw_origin_for_draw_command(is_screen_draw, bmp_target);
22322 118678442 script_drawing_commands[j].draw_origin = draw_origin;
22323 118678442 script_drawing_commands[j].draw_origin_target = draw_origin_target;
22324
22325 118678442 script_drawing_commands.mark_dirty(script_drawing_commands[j][1]/10000);
22326 118678442 }
22327
22328 7084216 void do_set_rendertarget(bool)
22329 {
22330 7084216 int32_t target = int32_t(SH::read_stack(ri->sp) / 10000);
22331 7084216 zscriptDrawingRenderTarget->SetCurrentRenderTarget(target);
22332 7084216 }
22333
22334 427914 void do_sfx(const bool v)
22335 {
22336 427914 int32_t ID = SH::get_arg(sarg1, v) / 10000;
22337
22338
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 427910 times.
427914 if(BC::checkSFXID(ID) != SH::_NoError)
22339 4 return;
22340
22341 427910 sfx(ID);
22342 427914 }
22343
22344 14 void do_sfx_ex(const bool restart)
22345 {
22346 14 int32_t ID = SH::read_stack(ri->sp + 4) / 10000;
22347 14 int32_t vol = vbound(SH::read_stack(ri->sp + 3), 0, 10000 * 100);
22348 14 int32_t pan = vbound(SH::read_stack(ri->sp + 2)/10000 + 128, 0, 255);
22349 14 int32_t freq = SH::read_stack(ri->sp + 1);
22350 14 bool loop = SH::read_stack(ri->sp) / 10000;
22351
22352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (BC::checkSFXID(ID) != SH::_NoError)
22353 return;
22354
22355
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 if (!restart && !sfx_allocated(ID))
22356 return;
22357
22358 14 sfx(ID, pan, loop, restart, vol, freq);
22359 14 }
22360
22361 static int get_sfx_completion()
22362 {
22363 int32_t ID = get_register(sarg1) / 10000;
22364
22365 if (!sfx_allocated(ID))
22366 {
22367 return -10000;
22368 }
22369
22370 int sample_pos = voice_get_position(sfx_voice[ID]);
22371 if (sample_pos < 0)
22372 {
22373 return -10000;
22374 }
22375
22376 uint32_t sample_length = sfx_get_length(ID);
22377 uint64_t res = ((uint64_t)sample_pos * 10000 * 100) / sample_length;
22378 return int32_t(res);
22379 }
22380
22381 void do_get_sfx_completion()
22382 {
22383 int32_t ID = get_register(sarg1) / 10000;
22384 if (replay_is_active())
22385 replay_step_comment(fmt::format("ID {}", ID));
22386 int32_t value = replay_get_state(ReplayStateType::SfxPosition, get_sfx_completion);
22387 set_register(sarg1, value);
22388 }
22389
22390 void FFScript::AlloffLimited(int32_t flagset)
22391 {
22392 clear_bitmap(msg_txt_display_buf);
22393 clear_bitmap(msg_bg_display_buf);
22394 clear_bitmap(msg_portrait_display_buf);
22395 set_clip_state(msg_txt_display_buf, 1);
22396 set_clip_state(msg_bg_display_buf, 1);
22397 set_clip_state(msg_portrait_display_buf, 1);
22398
22399
22400 clear_bitmap(pricesdisplaybuf);
22401 set_clip_state(pricesdisplaybuf, 1);
22402
22403 if(items.idCount(iPile))
22404 {
22405 loadlvlpal(DMaps[cur_dmap].color);
22406 }
22407
22408 /*
22409
22410 #define warpFlagCLEARITEMS 0x200
22411 #define warpFlagCLEARGUYS 0x400
22412 #define warpFlagCLEARLWEAPONS 0x800
22413 #define warpFlagCLEAREWEAPONS 0x1000
22414 #define warpFlagCLEARHOOKSHOT 0x2000
22415 #define warpFlagCLEARDECORATIONS 0x4000
22416 #define warpFlagCLEARPARTICLES 0x8000
22417 */
22418
22419 if ( (flagset&warpFlagCLEARITEMS) ) items.clear();
22420 if ( (flagset&warpFlagCLEARGUYS) ) guys.clear();
22421 if ( (flagset&warpFlagCLEARLWEAPONS) ) Lwpns.clear();
22422 if ( (flagset&warpFlagCLEAREWEAPONS) ) Ewpns.clear();
22423 if ( (flagset&warpFlagCLEARHOOKSHOT) )
22424 {
22425 chainlinks.clear();
22426 Hero.reset_hookshot();
22427 }
22428 if ( (flagset&warpFlagCLEARDECORATIONS) ) decorations.clear();
22429 if ( (flagset&warpFlagCLEARPARTICLES) ) particles.clear();
22430 clearScriptHelperData();
22431
22432
22433
22434 clearScriptHelperData();
22435
22436 lensclk = 0;
22437 lensid=-1;
22438 drawguys=true;
22439 down_control_states[btnUp] =
22440 down_control_states[btnDown] =
22441 down_control_states[btnLeft] =
22442 down_control_states[btnRight] =
22443 down_control_states[btnA] =
22444 down_control_states[btnB] =
22445 down_control_states[btnS] = true;
22446
22447 if(watch && !cheat_superman)
22448 {
22449 Hero.setClock(false);
22450 }
22451
22452 watch=freeze_guys=loaded_guys=blockpath=false;
22453
22454 activation_counters.fill({});
22455 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
22456 get_screen_state(scr->screen).loaded_enemies = false;
22457 });
22458
22459 sle_clk=0;
22460
22461 if(usebombpal)
22462 {
22463 memcpy(RAMpal, tempbombpal, PAL_SIZE*sizeof(RGB));
22464 refreshpal=true;
22465 usebombpal=false;
22466 }
22467
22468
22469 }
22470
22471 208 void doWarpEffect(int32_t warpEffect, bool out)
22472 {
22473
4/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 158 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 10 times.
208 switch(warpEffect)
22474 {
22475 case warpEffectZap:
22476 if(out) zapout();
22477 else zapin();
22478 break;
22479 case warpEffectWave:
22480
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if(out) wavyout(false);
22481 16 else wavyin();
22482 32 break;
22483 case warpEffectInstant:
22484
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if(out) blackscr(30,true);
22485 8 break;
22486 case warpEffectMozaic:
22487 //!TODO Unimplemented
22488 break;
22489 case warpEffectOpen:
22490
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if(out) closescreen();
22491 5 else openscreen();
22492 10 break;
22493 }
22494 208 }
22495
22496 14 void FFScript::queueWarp(int32_t wtype, int32_t tdm, int32_t tscr, int32_t wx, int32_t wy,
22497 int32_t weff, int32_t wsfx, int32_t wflag, int32_t wdir)
22498 {
22499 14 warpex[wexActive] = 1;
22500 14 warpex[wexType] = wtype;
22501 14 warpex[wexDMap] = tdm;
22502 14 warpex[wexScreen] = tscr;
22503 14 warpex[wexX] = wx;
22504 14 warpex[wexY] = wy;
22505 14 warpex[wexEffect] = weff;
22506 14 warpex[wexSound] = wsfx;
22507 14 warpex[wexFlags] = wflag;
22508 14 warpex[wexDir] = wdir;
22509 14 }
22510
22511 114 bool FFScript::warp_player(int32_t warpType, int32_t dmap, int32_t screen, int32_t warpDestX, int32_t warpDestY, int32_t warpEffect, int32_t warpSound, int32_t warpFlags, int32_t heroFacesDir)
22512 {
22513 if(DEVLOGGING)
22514 {
22515 zprint("FFScript::warp_player() arg %s is: %d \n", "warpType", warpType);
22516 zprint("FFScript::warp_player() arg %s is: %d \n", "dmap", dmap);
22517 zprint("FFScript::warp_player() arg %s is: %d \n", "screen", screen);
22518 zprint("FFScript::warp_player() arg %s is: %d \n", "warpDestX", warpDestX);
22519 zprint("FFScript::warp_player() arg %s is: %d \n", "warpDestY", warpDestY);
22520 zprint("FFScript::warp_player() arg %s is: %d \n", "warpEffect", warpEffect);
22521 zprint("FFScript::warp_player() arg %s is: %d \n", "warpSound", warpSound);
22522 zprint("FFScript::warp_player() arg %s is: %d \n", "warpFlags", warpFlags);
22523 zprint("FFScript::warp_player() arg %s is: %d \n", "heroFacesDir", heroFacesDir);
22524 }
22525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if ( ((unsigned)dmap) >= MAXDMAPS )
22526 {
22527 Z_scripterrlog("Invalid DMap ID (%d) passed to WarpEx(). Aborting.\n", dmap);
22528 return false;
22529 }
22530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if ( ((unsigned)screen) >= MAPSCRS )
22531 {
22532 Z_scripterrlog("Invalid Screen Index (%d) passed to WarpEx(). Aborting.\n", screen);
22533 return false;
22534 }
22535 //Extra sanity guard.
22536
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if ( map_screen_index(DMaps[dmap].map, screen + DMaps[dmap].xoff) >= (int32_t)TheMaps.size() )
22537 {
22538 Z_scripterrlog("Invalid destination passed to WarpEx(). Aborting.\n");
22539 return false;
22540 }
22541 114 byte t = 0;
22542 114 t=(cur_screen<128)?0:1;
22543 114 bool overlay=false;
22544 114 bool intradmap = (dmap == cur_dmap);
22545 114 int32_t olddmap = cur_dmap;
22546 //if ( intradmap )
22547 //{
22548 // initZScriptDMapScripts(); //Not needed.
22549 //}
22550
22551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if ( warpType == wtNOWARP ) { Z_eventlog("Used a Cancel Warped to DMap %d: %s, screen %d", cur_dmap, DMaps[cur_dmap].name,cur_screen); return false; }
22552 114 int32_t dest_map = DMaps[dmap].map;
22553 114 int32_t mapID = dest_map + 1;
22554 114 int32_t dest_dmap_xoff = DMaps[dmap].xoff;
22555 114 int32_t dest_screen = dest_dmap_xoff + screen;
22556 //mapscr *m = &TheMaps[mapID * MAPSCRS + scrID];
22557
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 mapscr *m = &TheMaps[(zc_max((mapID)-1,0) * MAPSCRS + dest_screen)];
22558
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 if ( warpFlags&warpFlagNOSTEPFORWARD ) FFCore.temp_no_stepforward = 1;
22559 114 int32_t wx = 0, wy = 0;
22560
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 93 times.
114 if ( warpDestX < 0 )
22561 {
22562 if(DEVLOGGING) zprint("WarpEx() was set to warp return point:%d\n", warpDestY);
22563
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 10 times.
93 if ( (unsigned)warpDestY < 4 )
22564 {
22565 83 wx = m->warpreturnx[warpDestY];
22566 83 wy = m->warpreturny[warpDestY];
22567 if(DEVLOGGING)
22568 {
22569 zprint("WarpEx Return Point X is: %d\n",wx);
22570 zprint("WarpEx Return Point Y is: %d\n",wy);
22571 }
22572 83 }
22573 else
22574 {
22575
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 if ( warpDestY == 5 || warpDestY < 0)
22576 {
22577 //Pit warp
22578 10 wx = Hero.getX();
22579 10 wy = Hero.getY();
22580 10 }
22581 else
22582 {
22583 Z_scripterrlog("Invalid Warp Return Square Type (%d) provided as an arg to Hero->WarpEx().\n",warpDestY);
22584 return false;
22585 }
22586 }
22587 93 }
22588 else
22589 {
22590 region_t region;
22591 int rx, ry;
22592 21 calculate_region(dest_map, dest_screen, region, rx, ry);
22593
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
21 if ( (unsigned)warpDestX < region.width && (unsigned)warpDestY < region.height )
22594 {
22595 21 wx = warpDestX;
22596 21 wy = warpDestY;
22597 21 }
22598 else
22599 {
22600 Z_scripterrlog("Invalid pixel coordinates of x = %d, y = %d, supplied to Hero->WarpEx()\n",warpDestX,warpDestY);
22601 return false;
22602 }
22603 }
22604 114 Hero.finish_auto_walk();
22605 //warp coordinates are wx, wy, not x, y! -Z
22606
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 60 times.
114 if ( !(warpFlags&warpFlagDONTKILLSCRIPTDRAWS) ) script_drawing_commands.Clear();
22607 //we also need to check if dmaps are sideview here! -Z
22608 //Likewise, we need to add that check to the normal Hero:;dowarp(0
22609 114 bool wasSideview = isSideViewGravity(t);
22610
22611 //int32_t last_entr_scr = -1;
22612 //int32_t last_entr_dmap = -1;
22613
22614
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 if ( warpType < wtEXIT ) warpType = wtIWARP; //Sanity check. We can't use wtCave, or wtPassage, with scritped warps at present.
22615 114 Hero.is_warping = true;
22616
2/5
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
114 switch(warpType)
22617 {
22618 case wtIWARP:
22619 case wtIWARPBLK:
22620 case wtIWARPOPEN:
22621 case wtIWARPZAP:
22622 case wtIWARPWAVE:
22623 {
22624 104 bool wasswimming = (Hero.getAction()==swimming);
22625 104 bool wassideswim = (Hero.getAction()==sideswimming);
22626 104 int32_t olddiveclk = Hero.diveclk;
22627
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 if ( !(warpFlags&warpFlagDONTCLEARSPRITES) )
22628 {
22629 104 ALLOFF();
22630 104 }
22631 else FFCore.AlloffLimited(warpFlags);
22632
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 86 times.
104 if (warpFlags&warpFlagFORCERESETMUSIC) music_stop();
22633
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 50 times.
104 if ( !(warpFlags&warpFlagDONTKILLSOUNDS) ) kill_sfx();
22634 104 sfx(warpSound);
22635
1/2
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
104 if(wasswimming)
22636 {
22637 Hero.setAction(swimming); FFCore.setHeroAction(swimming);
22638 Hero.set_dive(olddiveclk);
22639 }
22640
1/2
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
104 if(wassideswim)
22641 {
22642 Hero.setAction(sideswimming); FFCore.setHeroAction(sideswimming);
22643 Hero.set_dive(0);
22644 }
22645 104 doWarpEffect(warpEffect, true);
22646 104 int32_t c = DMaps[cur_dmap].color;
22647 104 bool changedlevel = false;
22648 104 bool changeddmap = false;
22649
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 74 times.
104 if(cur_dmap != dmap)
22650 {
22651 74 timeExitAllGenscript(GENSCR_ST_CHANGE_DMAP);
22652 74 changeddmap = true;
22653 74 }
22654
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 52 times.
104 if(dlevel != DMaps[dmap].level)
22655 {
22656 52 timeExitAllGenscript(GENSCR_ST_CHANGE_LEVEL);
22657 52 changedlevel = true;
22658 52 }
22659 104 dlevel = DMaps[dmap].level;
22660 104 cur_dmap = dmap;
22661
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 74 times.
104 if(changeddmap)
22662 {
22663 74 throwGenScriptEvent(GENSCR_EVENT_CHANGE_DMAP);
22664 74 }
22665
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 52 times.
104 if(changedlevel)
22666 {
22667 52 throwGenScriptEvent(GENSCR_EVENT_CHANGE_LEVEL);
22668 52 }
22669 104 cur_map = DMaps[cur_dmap].map;
22670 104 init_dmap();
22671 104 update_subscreens(dmap);
22672
22673 104 ringcolor(false);
22674
22675
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 70 times.
104 if(DMaps[cur_dmap].color != c)
22676 70 loadlvlpal(DMaps[cur_dmap].color);
22677
22678 104 lightingInstant(); // Also sets naturaldark
22679 104 int prev_screen = Hero.current_screen;
22680 104 loadscr(cur_dmap, screen + DMaps[cur_dmap].xoff, -1, overlay);
22681
22682 // In the case where we did not call ALLOFF, preserve the "enemies have spawned"
22683 // state for the new screen.
22684
1/2
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
104 if (warpFlags&warpFlagDONTCLEARSPRITES)
22685 {
22686 if (get_screen_state(prev_screen).loaded_enemies)
22687 get_screen_state(Hero.current_screen).loaded_enemies = true;
22688 }
22689
22690 104 Hero.x = (zfix)wx;
22691 104 Hero.y = (zfix)wy;
22692 104 update_viewport();
22693
22694
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 30 times.
104 switch(heroFacesDir)
22695 {
22696 case up:
22697 case down:
22698 case left:
22699 case right:
22700 74 Hero.dir = heroFacesDir;
22701 74 break;
22702 default:
22703
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if((int32_t)Hero.x==(zfix)0)
22704 {
22705 Hero.dir=right;
22706 }
22707
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if((int32_t)Hero.x==(zfix)240)
22708 {
22709 Hero.dir=left;
22710 }
22711
22712
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if((int32_t)Hero.y==(zfix)0)
22713 {
22714 Hero.dir=down;
22715 }
22716
22717
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if((int32_t)Hero.y==(zfix)160)
22718 {
22719 Hero.dir=up;
22720 }
22721 30 }
22722
22723 104 markBmap(Hero.dir^1, Hero.current_screen);
22724
22725
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 104 times.
104 if(iswaterex_z3(MAPCOMBO((int32_t)Hero.x,(int32_t)Hero.y+8), -1, Hero.x, Hero.y+8, true) && _walkflag((int32_t)Hero.x,(int32_t)Hero.y+8,0) && current_item(itype_flippers))
22726 {
22727 Hero.hopclk=0xFF;
22728 Hero.attackclk = Hero.charging = Hero.spins = 0;
22729 if (isSideViewHero() && get_qr(qr_SIDESWIM)) {Hero.setAction(sideswimming); FFCore.setHeroAction(sideswimming);}
22730 else {Hero.setAction(swimming); FFCore.setHeroAction(swimming);}
22731 }
22732 else
22733 {
22734 104 Hero.setAction(none); FFCore.setHeroAction(none);
22735 }
22736
22737 //preloaded freeform combos
22738 104 ffscript_engine(true);
22739
22740 104 putscr(hero_scr, scrollbuf, 0, 0);
22741 104 putscrdoors(hero_scr, scrollbuf, 0, 0);
22742
22743 104 doWarpEffect(warpEffect, false);
22744 104 show_subscreen_life=true;
22745 104 show_subscreen_numbers=true;
22746
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 100 times.
104 if (!(warpFlags&warpFlagFORCECONTINUEMUSIC)) Play_Level_Music();
22747 104 currcset=DMaps[cur_dmap].color;
22748 104 dointro();
22749 104 Hero.set_respawn_point();
22750 104 Hero.trySideviewLadder();
22751
22752 104 break;
22753 }
22754
22755
22756 case wtEXIT:
22757 {
22758 lighting(false,false,pal_litRESETONLY);//Reset permLit, and do nothing else; lighting was not otherwise called on a wtEXIT warp.
22759 ALLOFF();
22760 if (warpFlags&warpFlagFORCERESETMUSIC) music_stop();
22761 if ( !(warpFlags&warpFlagDONTKILLSOUNDS) ) kill_sfx();
22762 sfx(warpSound);
22763 blackscr(30,false);
22764 bool changedlevel = false;
22765 bool changeddmap = false;
22766 if(cur_dmap != dmap)
22767 {
22768 timeExitAllGenscript(GENSCR_ST_CHANGE_DMAP);
22769 changeddmap = true;
22770 }
22771 if(dlevel != DMaps[dmap].level)
22772 {
22773 timeExitAllGenscript(GENSCR_ST_CHANGE_LEVEL);
22774 changedlevel = true;
22775 }
22776 dlevel = DMaps[dmap].level;
22777 cur_dmap = dmap;
22778 if(changeddmap)
22779 {
22780 throwGenScriptEvent(GENSCR_EVENT_CHANGE_DMAP);
22781 }
22782 if(changedlevel)
22783 {
22784 throwGenScriptEvent(GENSCR_EVENT_CHANGE_LEVEL);
22785 }
22786 cur_map=DMaps[cur_dmap].map;
22787 init_dmap();
22788 update_subscreens(dmap);
22789 loadfullpal();
22790 ringcolor(false);
22791 loadlvlpal(DMaps[cur_dmap].color);
22792 loadscr(cur_dmap, screen + DMaps[cur_dmap].xoff, -1, overlay);
22793
22794 if((hero_scr->flags&fDARK) && !get_qr(qr_NEW_DARKROOM))
22795 {
22796 if(get_qr(qr_FADE))
22797 {
22798 interpolatedfade();
22799 }
22800 else
22801 {
22802 loadfadepal((DMaps[cur_dmap].color)*pdLEVEL+poFADE3);
22803 }
22804
22805 darkroom=naturaldark=true;
22806 }
22807 else
22808 {
22809 darkroom=naturaldark=false;
22810 }
22811
22812
22813 //Move Hero's coordinates
22814 Hero.x = (zfix)wx;
22815 Hero.y = (zfix)wy;
22816 update_viewport();
22817
22818 //set his dir
22819 switch(heroFacesDir)
22820 {
22821 case up:
22822 case down:
22823 case left:
22824 case right:
22825 Hero.dir = heroFacesDir;
22826 break;
22827 default:
22828 Hero.dir=down;
22829 if((int32_t)Hero.x==(zfix)0)
22830 {
22831 Hero.dir=right;
22832 }
22833 if((int32_t)Hero.x==(zfix)240)
22834 {
22835 Hero.dir=left;
22836 }
22837
22838 if((int32_t)Hero.y==(zfix)0)
22839 {
22840 Hero.dir=down;
22841 }
22842
22843 if((int32_t)Hero.y==(zfix)160)
22844 {
22845 Hero.dir=up;
22846 }
22847 }
22848
22849 if(dlevel)
22850 {
22851 // reset enemy kill counts
22852 for(int32_t i=0; i<128; i++)
22853 {
22854 int mi = mapind(cur_map, i);
22855 game->guys[mi] = 0;
22856 game->maps[mi] &= ~mTMPNORET;
22857 }
22858 }
22859
22860 markBmap(Hero.dir^1, Hero.current_screen);
22861 //preloaded freeform combos
22862 ffscript_engine(true);
22863 Hero.reset_hookshot();
22864
22865 if(isdungeon())
22866 {
22867 openscreen();
22868 if(get_er(er_SHORTDGNWALK)==0 && get_qr(qr_SHORTDGNWALK)==0)
22869 Hero.stepforward(Hero.diagonalMovement?11:12, false);
22870 else
22871 // Didn't walk as far pre-1.93, and some quests depend on that
22872 Hero.stepforward(8, false);
22873 }
22874 else
22875 {
22876 openscreen();
22877 }
22878
22879 show_subscreen_life=true;
22880 show_subscreen_numbers=true;
22881 if (!(warpFlags&warpFlagFORCECONTINUEMUSIC))Play_Level_Music();
22882 currcset=DMaps[cur_dmap].color;
22883 dointro();
22884 Hero.set_respawn_point();
22885 Hero.trySideviewLadder();
22886
22887 for(int32_t i=0; i<6; i++)
22888 visited[i]=-1;
22889
22890 //last_entr_scr = scrID;
22891 //last_entr_dmap = dmapID;
22892
22893 break;
22894
22895 }
22896 case wtSCROLL: // scrolling warp
22897 {
22898 10 int32_t c = DMaps[cur_dmap].color;
22899 10 scrolling_dmap = cur_dmap;
22900 10 scrolling_map = cur_map;
22901 10 cur_map = DMaps[dmap].map;
22902 10 update_subscreens(dmap);
22903
22904 10 dlevel = DMaps[dmap].level;
22905 //check if Hero has the map for the new location before updating the subscreen. ? -Z
22906 //This works only in one direction, if Hero had a map, to not having one.
22907 //If Hero does not have a map, and warps somewhere where he does, then the map still briefly shows.
22908 10 update_subscreens(dmap);
22909
22910 // if ( has_item(itype_map, dlevel) )
22911 // {
22912 // //Blank the map during an intra-dmap scrolling warp.
22913 // dlevel = -1; //a hack for the minimap. This works!! -Z
22914 // }
22915
22916 // fix the scrolling direction, if it was a tile or instant warp
22917 10 Hero.sdir = vbound(Hero.dir,0,3);
22918
22919
22920 10 Hero.scrollscr(Hero.sdir, screen+DMaps[dmap].xoff, dmap);
22921 10 bool changedlevel = false;
22922 10 bool changeddmap = false;
22923
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(cur_dmap != dmap)
22924 {
22925 timeExitAllGenscript(GENSCR_ST_CHANGE_DMAP);
22926 changeddmap = true;
22927 }
22928
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(dlevel != DMaps[dmap].level)
22929 {
22930 timeExitAllGenscript(GENSCR_ST_CHANGE_LEVEL);
22931 changedlevel = true;
22932 }
22933 10 dlevel = DMaps[dmap].level;
22934 10 cur_dmap = dmap;
22935
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(changeddmap)
22936 {
22937 throwGenScriptEvent(GENSCR_EVENT_CHANGE_DMAP);
22938 }
22939
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(changedlevel)
22940 {
22941 throwGenScriptEvent(GENSCR_EVENT_CHANGE_LEVEL);
22942 }
22943
22944 10 Hero.reset_hookshot();
22945
22946
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(!intradmap)
22947 {
22948
5/8
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
10 if(((wx>0||wy>0)||(get_qr(qr_WARPSIGNOREARRIVALPOINT)))&&(!get_qr(qr_NOSCROLLCONTINUE))&&(!(hero_scr->flags6&fNOCONTINUEHERE)))
22949 {
22950
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
10 if(dlevel)
22951 {
22952 6 lastentrance = cur_screen;
22953 6 }
22954 else
22955 {
22956 4 lastentrance = DMaps[cur_dmap].cont + DMaps[cur_dmap].xoff;
22957 }
22958
22959 10 lastentrance_dmap = dmap;
22960 10 }
22961 10 }
22962
22963
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(DMaps[cur_dmap].color != c)
22964 {
22965 lighting(false, true);
22966 }
22967
22968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!(warpFlags&warpFlagFORCECONTINUEMUSIC)) Play_Level_Music();
22969 10 currcset=DMaps[cur_dmap].color;
22970 10 dointro();
22971 10 break;
22972 }
22973 //Cannot use these types with scripts, or with strings.
22974 case wtCAVE:
22975 case wtPASS:
22976 case wtWHISTLE:
22977 default:
22978 {
22979 Z_scripterrlog("Invalid warp type (%d) supplied to Hero->WarpEx()!. Cannot warp!!\n", warpType);
22980 Hero.is_warping = false;
22981 return false;
22982 }
22983 }
22984 // Stop Hero from drowning!
22985
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 if(Hero.getAction()==drowning)
22986 {
22987 Hero.drownclk=0;
22988 Hero.setAction(none); FFCore.setHeroAction(none);
22989 }
22990
22991 // But keep him swimming if he ought to be!
22992
3/8
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 114 times.
✗ Branch 7 not taken.
114 if(Hero.getAction()!=rafting && iswaterex_z3(MAPCOMBO((int32_t)Hero.x,(int32_t)Hero.y+8), -1, Hero.x, Hero.y+8, true) && (_walkflag((int32_t)Hero.x,(int32_t)Hero.y+8,0) || get_qr(qr_DROWN))
22993 && (current_item(itype_flippers)) && (Hero.getAction()!=inwind))
22994 {
22995 Hero.hopclk=0xFF;
22996 if (isSideViewHero() && get_qr(qr_SIDESWIM)) {Hero.setAction(sideswimming); FFCore.setHeroAction(sideswimming);}
22997 else {Hero.setAction(swimming); FFCore.setHeroAction(swimming);}
22998 }
22999
23000 114 newscr_clk=frame;
23001 114 activated_timed_warp=false;
23002 114 eat_buttons();
23003
23004
2/2
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 33 times.
114 if(warpType!=wtIWARP) { Hero.attackclk=0; }
23005
23006 114 Hero.didstuff=0;
23007 114 Hero.usecounts.clear();
23008 114 map_bkgsfx(true);
23009 114 loadside=Hero.dir^1;
23010 114 whistleclk=-1;
23011
23012
2/4
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
114 if(((int32_t)Hero.z>0 || (int32_t)Hero.fakez>0) && isSideViewHero())
23013 {
23014 Hero.y-=Hero.z;
23015 Hero.y-=Hero.fakez;
23016 Hero.z=0;
23017 Hero.fakez=0;
23018 }
23019
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 113 times.
114 else if(!isSideViewHero())
23020 {
23021 113 Hero.fall=0;
23022 113 Hero.fakefall=0;
23023 113 }
23024
23025 // If warping between top-down and sideview screens,
23026 // fix enemies that are carried over by Full Screen Warp
23027 114 const bool tmpscr_is_sideview = isSideViewGravity();
23028
23029
3/4
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 113 times.
✓ Branch 3 taken 1 times.
114 if(!wasSideview && tmpscr_is_sideview)
23030 {
23031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for(int32_t i=0; i<guys.Count(); i++)
23032 {
23033 if(guys.spr(i)->z > 0)
23034 {
23035 guys.spr(i)->y -= guys.spr(i)->z;
23036 guys.spr(i)->z = 0;
23037 }
23038
23039 if(((enemy*)guys.spr(i))->type!=eeTRAP && ((enemy*)guys.spr(i))->type!=eeSPINTILE)
23040 guys.spr(i)->yofs += 2;
23041 }
23042 1 }
23043
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
113 else if(wasSideview && !tmpscr_is_sideview)
23044 {
23045 for(int32_t i=0; i<guys.Count(); i++)
23046 {
23047 if(((enemy*)guys.spr(i))->type!=eeTRAP && ((enemy*)guys.spr(i))->type!=eeSPINTILE)
23048 guys.spr(i)->yofs -= 2;
23049 }
23050 }
23051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if ( warpType == wtEXIT )
23052 {
23053 game->set_continue_scrn(cur_screen);
23054 game->set_continue_dmap(dmap);
23055 lastentrance = cur_screen;
23056 lastentrance_dmap = dmap;
23057 }
23058 else
23059 {
23060
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 4 times.
114 if ( (warpFlags&warpFlagSETENTRANCESCREEN) ) lastentrance = cur_screen;
23061
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 4 times.
114 if ( (warpFlags&warpFlagSETENTRANCEDMAP) ) lastentrance_dmap = dmap;
23062
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 4 times.
114 if ( (warpFlags&warpFlagSETCONTINUESCREEN) ) game->set_continue_scrn(cur_screen);
23063
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 4 times.
114 if ( (warpFlags&warpFlagSETCONTINUEDMAP) ) game->set_continue_dmap(dmap);
23064 }
23065
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 if(hero_scr->flags4&fAUTOSAVE)
23066 {
23067 save_game(true,0);
23068 }
23069
23070
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 2 times.
114 if(hero_scr->flags6&fCONTINUEHERE)
23071 {
23072 2 lastentrance_dmap = cur_dmap;
23073 2 lastentrance = home_screen;
23074 2 }
23075
23076 114 update_subscreens();
23077 114 verifyBothWeapons();
23078 228 Z_eventlog("Warped to DMap %d: %s, screen %d, via %s.\n", cur_dmap, DMaps[cur_dmap].name,cur_screen,
23079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
228 warpType==wtEXIT ? "Entrance/Exit" :
23080
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 104 times.
114 warpType==wtSCROLL ? "Scrolling Warp" :
23081 104 warpType==wtNOWARP ? "Cancel Warp" :
23082 "Insta-Warp");
23083
23084 114 eventlog_mapflags();
23085
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 106 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
114 if (((warpFlags&warpFlagDONTRESTARTDMAPSCRIPT) != 0) == (get_qr(qr_SCRIPT_WARPS_DMAP_SCRIPT_TOGGLE) != 0)|| olddmap != cur_dmap) //Changed DMaps, or needs to reset the script
23086 {
23087 110 FFScript::deallocateAllScriptOwned(ScriptType::DMap, olddmap);
23088 110 initZScriptDMapScripts();
23089 110 }
23090 114 Hero.is_warping = false;
23091
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 90 times.
114 if(!get_qr(qr_SCROLLWARP_NO_RESET_FRAME))
23092 90 GameFlags |= GAMEFLAG_RESET_GAME_LOOP;
23093 114 return true;
23094 114 }
23095
23096 2004 void FFScript::do_adjustvolume(const bool v)
23097 {
23098
1/2
✓ Branch 0 taken 2004 times.
✗ Branch 1 not taken.
2004 if (get_qr(qr_OLD_SCRIPT_VOLUME))
23099 {
23100 2004 int32_t perc = (SH::get_arg(sarg1, v) / 10000);
23101 2004 float pct = perc / 100.0;
23102 2004 float temp_midi = 0;
23103 2004 float temp_digi = 0;
23104 2004 float temp_mus = 0;
23105
2/2
✓ Branch 0 taken 2000 times.
✓ Branch 1 taken 4 times.
2004 if (!(coreflags & FFCORE_SCRIPTED_MIDI_VOLUME))
23106 {
23107 4 temp_midi = do_getMIDI_volume();
23108 4 usr_midi_volume = do_getMIDI_volume();
23109 4 SetFFEngineFlag(FFCORE_SCRIPTED_MIDI_VOLUME, true);
23110 4 }
23111 else
23112 {
23113 2000 temp_midi = (float)usr_midi_volume;
23114 }
23115
2/2
✓ Branch 0 taken 2000 times.
✓ Branch 1 taken 4 times.
2004 if (!(coreflags & FFCORE_SCRIPTED_DIGI_VOLUME))
23116 {
23117 4 temp_digi = do_getDIGI_volume();
23118 4 usr_digi_volume = do_getDIGI_volume();
23119 4 SetFFEngineFlag(FFCORE_SCRIPTED_DIGI_VOLUME, true);
23120 4 }
23121 else
23122 {
23123 2000 temp_digi = (float)usr_digi_volume;
23124 }
23125
2/2
✓ Branch 0 taken 2000 times.
✓ Branch 1 taken 4 times.
2004 if (!(coreflags & FFCORE_SCRIPTED_MUSIC_VOLUME))
23126 {
23127 4 temp_mus = do_getMusic_volume();
23128 4 usr_music_volume = do_getMusic_volume();
23129 4 SetFFEngineFlag(FFCORE_SCRIPTED_MUSIC_VOLUME, true);
23130 4 }
23131 else
23132 {
23133 2000 temp_mus = (float)usr_music_volume;
23134 }
23135
23136 2004 temp_midi *= pct;
23137 2004 temp_digi *= pct;
23138 2004 temp_mus *= pct;
23139 2004 do_setMIDI_volume((int32_t)temp_midi);
23140 2004 do_setDIGI_volume((int32_t)temp_digi);
23141 2004 do_setMusic_volume((int32_t)temp_mus);
23142 2004 }
23143 else
23144 {
23145 int32_t perc = SH::get_arg(sarg1, v);
23146 FFCore.usr_music_volume = vbound(perc, 0, 10000 * 100);
23147
23148 if (zcmusic != NULL)
23149 {
23150 if (zcmusic->playing != ZCM_STOPPED)
23151 {
23152 int32_t temp_volume = emusic_volume;
23153 if (!get_qr(qr_OLD_SCRIPT_VOLUME))
23154 temp_volume = (emusic_volume * FFCore.usr_music_volume) / 10000 / 100;
23155 temp_volume = (temp_volume * zcmusic->fadevolume) / 10000;
23156 zcmusic_play(zcmusic, temp_volume);
23157 return;
23158 }
23159 }
23160 else if (currmidi > -1)
23161 {
23162 jukebox(currmidi);
23163 master_volume(digi_volume, midi_volume);
23164 }
23165 }
23166 2004 }
23167
23168 void FFScript::do_adjustsfxvolume(const bool v)
23169 {
23170 if (get_qr(qr_OLD_SCRIPT_VOLUME))
23171 {
23172 int32_t perc = (SH::get_arg(sarg1, v) / 10000);
23173 float pct = perc / 100.0;
23174 float temp_sfx = 0;
23175 if (!(coreflags & FFCORE_SCRIPTED_SFX_VOLUME))
23176 {
23177 temp_sfx = do_getSFX_volume();
23178 usr_sfx_volume = (int32_t)temp_sfx;
23179 SetFFEngineFlag(FFCORE_SCRIPTED_SFX_VOLUME, true);
23180 }
23181 else
23182 {
23183 temp_sfx = (float)usr_sfx_volume;
23184 }
23185 temp_sfx *= pct;
23186 do_setSFX_volume((int32_t)temp_sfx);
23187 }
23188 else
23189 {
23190 int32_t perc = SH::get_arg(sarg1, v);
23191 FFCore.usr_sfx_volume = vbound(perc, 0, 10000 * 100);
23192 }
23193 }
23194
23195
23196 63830 void do_midi(bool v)
23197 {
23198 63830 int32_t MIDI = SH::get_arg(sarg1, v) / 10000;
23199
23200
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 63786 times.
63830 if(MIDI == 0)
23201 44 music_stop();
23202 else
23203 63786 jukebox(MIDI + (ZC_MIDI_COUNT - 1));
23204 63830 }
23205
23206
23207 1 void stop_sfx(const bool v)
23208 {
23209 1 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23210 1 int32_t sfx = (int32_t)ID;
23211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(BC::checkSFXID(ID) != SH::_NoError)
23212 return;
23213 1 stop_sfx(sfx);
23214 1 }
23215
23216 void pause_sfx(const bool v)
23217 {
23218 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23219 int32_t sfx = (int32_t)ID;
23220 if(BC::checkSFXID(ID) != SH::_NoError)
23221 return;
23222 pause_sfx(sfx);
23223 }
23224
23225 void resume_sfx(const bool v)
23226 {
23227 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23228 int32_t sfx = (int32_t)ID;
23229 if(BC::checkSFXID(ID) != SH::_NoError)
23230 return;
23231 resume_sfx(sfx);
23232 }
23233
23234
23235
23236 357 void do_enh_music(bool v)
23237 {
23238 357 int32_t arrayptr = SH::get_arg(sarg1, v);
23239 357 int32_t track = (SH::get_arg(sarg2, v) / 10000)-1;
23240
23241
2/2
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 131 times.
357 if(arrayptr == 0)
23242 131 music_stop();
23243 else // Pointer to a string..
23244 {
23245 226 string filename_str;
23246 char filename_char[256];
23247 bool ret;
23248
1/2
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
226 ArrayH::getString(arrayptr, filename_str, 256);
23249 226 strncpy(filename_char, filename_str.c_str(), 255);
23250 226 filename_char[255]='\0';
23251
2/4
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✗ Branch 3 not taken.
226 ret=try_zcmusic(filename_char, qstpath, track, -1000, get_emusic_volume());
23252
1/2
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
226 set_register(sarg2, ret ? 10000 : 0);
23253 226 }
23254 357 }
23255
23256 5 void do_enh_music_crossfade()
23257 {
23258 5 int32_t arrayptr = SH::read_stack(ri->sp + 5);
23259 5 int32_t track = SH::read_stack(ri->sp + 4) / 10000;
23260
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 int32_t fadeoutframes = zc_max(SH::read_stack(ri->sp + 3) / 10000, 0);
23261
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 int32_t fadeinframes = zc_max(SH::read_stack(ri->sp + 2) / 10000, 0);
23262 5 int32_t fademiddleframes = SH::read_stack(ri->sp + 1) / 10000;
23263 5 int32_t startpos = SH::read_stack(ri->sp);
23264
23265
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (arrayptr == 0)
23266 {
23267 bool ret = play_enh_music_crossfade(NULL, qstpath, track, get_emusic_volume(), fadeoutframes, fadeinframes, fademiddleframes, startpos);
23268 SET_D(rEXP1, ret ? 10000 : 0);
23269 }
23270 else
23271 {
23272 5 string filename_str;
23273 char filename_char[256];
23274
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 ArrayH::getString(arrayptr, filename_str, 256);
23275 5 strncpy(filename_char, filename_str.c_str(), 255);
23276 5 filename_char[255] = '\0';
23277
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 bool ret = play_enh_music_crossfade(filename_char, qstpath, track, get_emusic_volume(), fadeoutframes, fadeinframes, fademiddleframes, startpos, true);
23278 5 SET_D(rEXP1, ret ? 10000 : 0);
23279 5 }
23280 5 }
23281
23282 bool FFScript::doing_dmap_enh_music(int32_t dm)
23283 {
23284 if (DMaps[dm].tmusic[0] != 0)
23285 {
23286 if (zcmusic != NULL)
23287 {
23288 if (strcmp(zcmusic->filename, DMaps[dm].tmusic) == 0)
23289 {
23290 switch (zcmusic_get_type(zcmusic))
23291 {
23292 case ZCMF_OGG:
23293 case ZCMF_MP3:
23294 return true;
23295 case ZCMF_DUH:
23296 case ZCMF_GME:
23297 if (zcmusic->track == DMaps[dm].tmusictrack)
23298 {
23299 return true;
23300 }
23301 }
23302 }
23303 }
23304 }
23305 return false;
23306 }
23307
23308 40525 bool FFScript::can_dmap_change_music(int32_t dm)
23309 {
23310
1/4
✓ Branch 0 taken 40525 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
40525 switch (music_update_cond)
23311 {
23312 case MUSIC_UPDATE_SCREEN:
23313 40525 return true;
23314 case MUSIC_UPDATE_DMAP:
23315 return dm != -1 && dm != cur_dmap;
23316 case MUSIC_UPDATE_LEVEL:
23317 return dm != -1 && DMaps[dm].level != DMaps[cur_dmap].level;
23318 }
23319 return false;
23320 40525 }
23321
23322 void FFScript::do_set_music_position(const bool v)
23323 {
23324 int32_t newposition = SH::get_arg(sarg1, v);
23325
23326 set_zcmusicpos(newposition);
23327 }
23328
23329 void FFScript::do_get_music_position()
23330 {
23331 int32_t pos = replay_get_state(ReplayStateType::MusicPosition, [](){
23332 return zcmusic_get_curpos(zcmusic);
23333 });
23334 set_register(sarg1, pos);
23335 }
23336
23337 void FFScript::do_set_music_speed(const bool v)
23338 {
23339 int32_t newspeed = SH::get_arg(sarg1, v);
23340 set_zcmusicspeed(newspeed);
23341 }
23342
23343 void FFScript::do_get_music_length()
23344 {
23345 int32_t len = get_zcmusiclen();
23346 set_register(sarg1, len);
23347 }
23348
23349 3 void FFScript::do_set_music_loop()
23350 {
23351 3 double start = (get_register(sarg1) / 10000.0);
23352 3 double end = (get_register(sarg2) / 10000.0);
23353
23354 3 set_zcmusicloop(start, end);
23355 3 }
23356
23357 236 void do_get_enh_music_filename(const bool v)
23358 {
23359 236 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23360 236 int32_t arrayptr = get_register(sarg2);
23361
23362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 if(BC::checkDMapID(ID) != SH::_NoError)
23363 return;
23364
23365
3/6
✓ Branch 0 taken 236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 236 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 236 times.
✗ Branch 5 not taken.
236 if(ArrayH::setArray(arrayptr, string(DMaps[ID].tmusic)) == SH::_Overflow)
23366 Z_scripterrlog("Array supplied to 'Game->GetDMapMusicFilename' not large enough\n");
23367 236 }
23368
23369 140 void do_get_enh_music_track(const bool v)
23370 {
23371 140 int32_t ID = SH::get_arg(sarg1, v) / 10000;
23372
23373
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 132 times.
140 if(BC::checkDMapID(ID) != SH::_NoError)
23374 8 return;
23375
23376 132 set_register(sarg1, (DMaps[ID].tmusictrack+1)*10000);
23377 140 }
23378
23379 3807 void do_set_dmap_enh_music(const bool v)
23380 {
23381 3807 int32_t ID = SH::read_stack(ri->sp + 2) / 10000;
23382 3807 int32_t arrayptr = SH::read_stack(ri->sp + 1);
23383 3807 int32_t track = (SH::read_stack(ri->sp + 0) / 10000)-1;
23384 3807 string filename_str;
23385
23386
2/4
✓ Branch 0 taken 3807 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3807 times.
✗ Branch 3 not taken.
3807 if(BC::checkDMapID(ID) != SH::_NoError)
23387 return;
23388
23389
1/2
✓ Branch 0 taken 3807 times.
✗ Branch 1 not taken.
3807 ArrayH::getString(arrayptr, filename_str, 56);
23390 3807 strncpy(DMaps[ID].tmusic, filename_str.c_str(), 55);
23391 3807 DMaps[ID].tmusic[55]='\0';
23392 3807 DMaps[ID].tmusictrack=track;
23393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3807 times.
3807 }
23394
23395
23396
23397
23398
23399
23400 ///----------------------------------------------------------------------------------------------------//
23401 //Array & string related
23402
23403 303089179 void do_arraysize()
23404 {
23405 303089179 int32_t arrayptr = get_register(sarg1);
23406 303089179 SET_D(rEXP1, ArrayH::getSize(arrayptr) * 10000);
23407 303089179 }
23408
23409 void do_tobyte()
23410 {
23411 int32_t b1 = get_register(sarg1) / 10000;
23412 byte b2 = b1;
23413 set_register(sarg1, b2 * 10000);
23414 }
23415
23416 void do_tosignedbyte()
23417 {
23418 int32_t b1 = get_register(sarg1) / 10000;
23419 signed char b2 = b1;
23420 set_register(sarg1, b2 * 10000);
23421 }
23422
23423 void do_tointeger()
23424 {
23425 int32_t b1 = get_register(sarg1) / 10000;
23426 set_register(sarg1, b1 * 10000);
23427 }
23428
23429 void do_floor()
23430 {
23431 set_register(sarg1, zslongToFix(get_register(sarg1)).doFloor().getZLong());
23432 }
23433
23434 void do_trunc()
23435 {
23436 set_register(sarg1, zslongToFix(get_register(sarg1)).doTrunc().getZLong());
23437 }
23438
23439 void do_ceiling()
23440 {
23441 set_register(sarg1, zslongToFix(get_register(sarg1)).doCeil().getZLong());
23442 }
23443
23444 void do_round()
23445 {
23446 set_register(sarg1, zslongToFix(get_register(sarg1)).doRound().getZLong());
23447 }
23448
23449 void do_roundaway()
23450 {
23451 set_register(sarg1, zslongToFix(get_register(sarg1)).doRoundAway().getZLong());
23452 }
23453
23454 void do_toword()
23455 {
23456 int32_t b1 = get_register(sarg1) / 10000;
23457 word b2 = b1;
23458 set_register(sarg1, b2 * 10000);
23459 }
23460
23461 void do_toshort()
23462 {
23463 int32_t b1 = get_register(sarg1) / 10000;
23464 int16_t b2 = b1;
23465 set_register(sarg1, b2 * 10000);
23466 }
23467
23468 //Set npc and item names t.b.a. -Z
23469
23470 2768 void do_getitemname()
23471 {
23472 2768 int32_t arrayptr = get_register(sarg1);
23473
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2768 times.
2768 if(unsigned(GET_REF(itemdataref)) >= MAXITEMS)
23474 {
23475 scripting_log_error_with_context("Invalid itemdata access: {}", GET_REF(itemdataref));
23476 return;
23477 }
23478
23479
3/6
✓ Branch 0 taken 2768 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2768 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2768 times.
✗ Branch 5 not taken.
2768 if(ArrayH::setArray(arrayptr, item_string[GET_REF(itemdataref)]) == SH::_Overflow)
23480 Z_scripterrlog("Array supplied to 'itemdata->GetName' not large enough\n");
23481 2768 }
23482
23483 10105657 void do_getffcscript()
23484 {
23485 10105657 do_get_script_index_by_name(name_to_slot_index_ffcmap);
23486 10105657 }
23487
23488 80 void do_getitemscript()
23489 {
23490 80 do_get_script_index_by_name(name_to_slot_index_itemmap);
23491 80 }
23492
23493 ///----------------------------------------------------------------------------------------------------//
23494 //Tile Manipulation
23495
23496 49289145 void do_copytile(const bool v, const bool v2)
23497 {
23498 49289145 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23499 49289145 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23500
23501 49289145 copy_tile(newtilebuf, tile, tile2, false);
23502 49289145 }
23503
23504 int32_t FFScript::IsBlankTile(int32_t i)
23505 {
23506 if( ((unsigned)i) > NEWMAXTILES )
23507 {
23508 scripting_log_error_with_context("Invalid tile ID {}", i);
23509 return -1;
23510 }
23511
23512 byte *tilestart=newtilebuf[i].data;
23513 qword *di=(qword*)tilestart;
23514 int32_t parts=tilesize(newtilebuf[i].format)>>3;
23515
23516 for(int32_t j=0; j<parts; ++j, ++di)
23517 {
23518 if(*di!=0)
23519 {
23520 return 0;
23521 }
23522 }
23523
23524 return 1;
23525 }
23526
23527 int32_t FFScript::Is8BitTile(int32_t i)
23528 {
23529 if (((unsigned)i) > NEWMAXTILES)
23530 {
23531 scripting_log_error_with_context("Invalid tile ID {}", i);
23532 return -1;
23533 }
23534
23535 return newtilebuf[i].format == tf8Bit ? 1 : 0;
23536 }
23537
23538 void do_swaptile(const bool v, const bool v2)
23539 {
23540 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23541 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23542
23543 copy_tile(newtilebuf, tile, tile2, true);
23544 }
23545
23546 57032 void do_overlaytile(const bool v, const bool v2)
23547 {
23548 57032 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23549 57032 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23550
23551
2/4
✓ Branch 0 taken 57032 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57032 times.
✗ Branch 3 not taken.
57032 if(BC::checkTile(tile) != SH::_NoError ||
23552 57032 BC::checkTile(tile2) != SH::_NoError)
23553 return;
23554
23555 //Could add an arg for the CSet or something instead of just passing 0, currently only 8-bit is supported
23556 57032 overlay_tile(newtilebuf, tile, tile2, 0, false);
23557 57032 }
23558
23559 void do_fliprotatetile(const bool v, const bool v2)
23560 {
23561 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23562 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23563
23564 if(BC::checkTile(tile) != SH::_NoError ||
23565 BC::checkTile(tile2) != SH::_NoError)
23566 return;
23567
23568 //fliprotatetile
23569 }
23570
23571 void do_settilepixel()
23572 {
23573 int32_t tile = SH::read_stack(ri->sp + 3) / 10000;
23574 int32_t x = SH::read_stack(ri->sp + 2) / 10000;
23575 int32_t y = SH::read_stack(ri->sp + 1) / 10000;
23576 int32_t val = SH::read_stack(ri->sp + 0) / 10000;
23577
23578 if(BC::checkTile(tile) != SH::_NoError)
23579 return;
23580
23581 x = vbound(x, 0, 15);
23582 y = vbound(y, 0, 15);
23583 unpack_tile(newtilebuf, tile, 0, false);
23584 if (newtilebuf[tile].format == tf4Bit)
23585 val &= 0xF;
23586 unpackbuf[y * 16 + x] = val;
23587 pack_tile(newtilebuf, unpackbuf, tile);
23588 }
23589
23590 void do_gettilepixel()
23591 {
23592 int32_t tile = SH::read_stack(ri->sp + 3) / 10000;
23593 int32_t x = SH::read_stack(ri->sp + 2) / 10000;
23594 int32_t y = SH::read_stack(ri->sp + 1) / 10000;
23595 int32_t cs = SH::read_stack(ri->sp + 0) / 10000;
23596
23597 if(BC::checkTile(tile) != SH::_NoError)
23598 return;
23599
23600 x = vbound(x, 0, 15);
23601 y = vbound(y, 0, 15);
23602 unpack_tile(newtilebuf, tile, 0, false);
23603 int32_t csoffs = newtilebuf[tile].format == tf8Bit ? 0 : cs * 16;
23604 SET_D(rEXP1, 10000 * (unpackbuf[y * 16 + x] + csoffs));
23605 }
23606
23607 void do_shifttile(const bool v, const bool v2)
23608 {
23609 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23610 int32_t tile2 = SH::get_arg(sarg2, v2) / 10000;
23611
23612 if(BC::checkTile(tile) != SH::_NoError ||
23613 BC::checkTile(tile2) != SH::_NoError)
23614 return;
23615
23616 //shifttile
23617 }
23618
23619 10 void do_cleartile(const bool v)
23620 {
23621 10 int32_t tile = SH::get_arg(sarg1, v) / 10000;
23622
23623
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(BC::checkTile(tile) != SH::_NoError)
23624 return;
23625
23626 10 reset_tile(newtilebuf, tile, newtilebuf[tile].format);
23627 10 }
23628
23629 3182 void do_combotile(const bool v)
23630 {
23631 3182 int32_t combo = SH::get_arg(sarg2, v) / 10000;
23632
23633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3182 times.
3182 if(BC::checkCombo(combo) != SH::_NoError)
23634 return;
23635
23636 3182 set_register(sarg1, combobuf[combo].tile * 10000);
23637 3182 }
23638
23639 316529659 void do_readpod(const bool v)
23640 {
23641 316529659 int32_t indx = SH::get_arg(sarg2, v) / 10000;
23642 316529659 int32_t val = ArrayH::getElement(GET_D(rINDEX), indx, can_neg_array);
23643 316529659 set_register(sarg1, val);
23644 316529659 }
23645 144938143 void do_writepod(const bool v1, const bool v2)
23646 {
23647 144938143 int32_t indx = SH::get_arg(sarg1, v1) / 10000;
23648 144938143 int32_t val = SH::get_arg(sarg2, v2);
23649 144938143 ArrayH::setElement(GET_D(rINDEX), indx, val, can_neg_array);
23650 144938143 }
23651 3274079 void do_writepodstr()
23652 {
23653
2/2
✓ Branch 0 taken 30329 times.
✓ Branch 1 taken 3243750 times.
3274079 if(!sargstr) return;
23654 3243750 uint32_t id = get_register(sarg1);
23655 3243750 ArrayH::setArray(id, *sargstr);
23656 3274079 }
23657 569712 void do_writepodarr()
23658 {
23659
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 569712 times.
569712 if(!sargvec) return;
23660
23661 569712 uint32_t id = get_register(sarg1);
23662 569712 ArrayH::setArray(id, sargvec->size(), sargvec->data(), false);
23663 569712 }
23664
23665 3960 sprite* get_own_sprite(ScriptType type)
23666 {
23667
2/7
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3935 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
3960 switch(type)
23668 {
23669 case ScriptType::None:
23670 25 return ResolveBaseSprite(GET_REF(spriteref));
23671 case ScriptType::Lwpn:
23672 return checkLWpn(GET_REF(lwpnref));
23673 case ScriptType::Ewpn:
23674 return checkEWpn(GET_REF(ewpnref));
23675 case ScriptType::ItemSprite:
23676 return checkItem(GET_REF(itemref));
23677 case ScriptType::NPC:
23678 3935 return checkNPC(GET_REF(npcref));
23679 case ScriptType::FFC:
23680 return ResolveFFC(GET_REF(ffcref));
23681 }
23682 return nullptr;
23683 3960 }
23684
23685 portal* loadportal(savedportal& p);
23686
23687 ///----------------------------------------------------------------------------------------------------//
23688 // Run the script //
23689 ///----------------------------------------------------------------------------------------------------//
23690
23691 11334412 static bool check_cmp(uint cmp)
23692 {
23693
2/2
✓ Branch 0 taken 5431 times.
✓ Branch 1 taken 11328981 times.
11334412 if(cmp & CMP_BOOL)
23694 {
23695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5431 times.
5431 if(ri->cmp_strcache) return false; //Cast string to bool? nonsense...
23696
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 5431 times.
5431 switch(cmp & CMP_FLAGS)
23697 {
23698 case CMP_EQ:
23699 return !ri->cmp_op1 == !ri->cmp_op2;
23700 case CMP_NE:
23701 5431 return !ri->cmp_op1 != !ri->cmp_op2;
23702 }
23703 return false;
23704 }
23705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11328981 times.
11328981 else if(ri->cmp_strcache)
23706 {
23707 if(*ri->cmp_strcache < 0)
23708 return (cmp & CMP_LT);
23709 if(*ri->cmp_strcache > 0)
23710 return (cmp & CMP_GT);
23711 return (cmp & CMP_EQ);
23712 }
23713 else
23714 {
23715
2/2
✓ Branch 0 taken 2793958 times.
✓ Branch 1 taken 8535023 times.
11328981 if(cmp & CMP_GT)
23716
2/2
✓ Branch 0 taken 2480013 times.
✓ Branch 1 taken 6055010 times.
8535023 if(ri->cmp_op1 > ri->cmp_op2)
23717 2480013 return true;
23718
2/2
✓ Branch 0 taken 6146318 times.
✓ Branch 1 taken 2702650 times.
8848968 if(cmp & CMP_LT)
23719
2/2
✓ Branch 0 taken 1795070 times.
✓ Branch 1 taken 907580 times.
2702650 if(ri->cmp_op1 < ri->cmp_op2)
23720 1795070 return true;
23721
2/2
✓ Branch 0 taken 2849904 times.
✓ Branch 1 taken 4203994 times.
7053898 if(cmp & CMP_EQ)
23722
2/2
✓ Branch 0 taken 1020506 times.
✓ Branch 1 taken 3183488 times.
4203994 if(ri->cmp_op1 == ri->cmp_op2)
23723 1020506 return true;
23724 6033392 return false;
23725 }
23726 11334412 }
23727
23728 7133 static void markRegisterType(int reg, int type)
23729 {
23730 // Currently only marking globals as objects is supported.
23731
1/2
✓ Branch 0 taken 7133 times.
✗ Branch 1 not taken.
7133 if (!(reg >= GD(0) && reg <= GD(MAX_SCRIPT_REGISTERS)))
23732 {
23733 assert(false);
23734 }
23735
1/2
✓ Branch 0 taken 7133 times.
✗ Branch 1 not taken.
7133 if (!(type >= 0 && type <= (int)script_object_type::last))
23736 {
23737 assert(false);
23738 }
23739
23740 7133 int index = reg - GD(0);
23741 7133 game->global_d_types[index] = (script_object_type)type;
23742 7133 }
23743
23744 1149 static void markGlobalRegisters()
23745 {
23746 word scommand;
23747 1149 auto& init_script = *globalscripts[GLOBAL_SCRIPT_INIT];
23748
2/2
✓ Branch 0 taken 683 times.
✓ Branch 1 taken 466 times.
1149 if (!init_script.valid())
23749 466 return;
23750
23751 683 auto& zasm = init_script.zasm_script->zasm;
23752 683 uint32_t start_pc = init_script.pc, end_pc = init_script.end_pc;
23753
23754
2/2
✓ Branch 0 taken 683 times.
✓ Branch 1 taken 526580 times.
527263 for (auto pc = start_pc; pc < end_pc; pc++)
23755 {
23756 526580 scommand = zasm[pc].command;
23757
2/2
✓ Branch 0 taken 522445 times.
✓ Branch 1 taken 4135 times.
526580 if(scommand == MARK_TYPE_REG)
23758 4135 markRegisterType(zasm[pc].arg1, zasm[pc].arg2);
23759 526580 }
23760 1149 }
23761
23762 void goto_err(char const* opname)
23763 {
23764 auto i = curScriptIndex;
23765 const char* type_str = ScriptTypeToString(curScriptType);
23766 switch(curScriptType)
23767 {
23768 case ScriptType::FFC:
23769 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, ffcmap[i].scriptname.c_str(), opname, sarg1); break;
23770 case ScriptType::NPC:
23771 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, npcmap[i].scriptname.c_str(), opname, sarg1); break;
23772 case ScriptType::Lwpn:
23773 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, lwpnmap[i].scriptname.c_str(), opname, sarg1); break;
23774 case ScriptType::Ewpn:
23775 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, ewpnmap[i].scriptname.c_str(), opname, sarg1); break;
23776 case ScriptType::ItemSprite:
23777 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, itemspritemap[i].scriptname.c_str(), opname, sarg1); break;
23778 case ScriptType::Item:
23779 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, itemmap[i].scriptname.c_str(), opname, sarg1); break;
23780 case ScriptType::Global:
23781 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, globalmap[i].scriptname.c_str(), opname, sarg1); break;
23782 case ScriptType::Hero:
23783 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, playermap[i].scriptname.c_str(), opname, sarg1); break;
23784 case ScriptType::Screen:
23785 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, screenmap[i].scriptname.c_str(), opname, sarg1); break;
23786 case ScriptType::OnMap:
23787 case ScriptType::DMap:
23788 case ScriptType::ScriptedActiveSubscreen:
23789 case ScriptType::ScriptedPassiveSubscreen:
23790 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, dmapmap[i].scriptname.c_str(), opname, sarg1); break;
23791 case ScriptType::Combo:
23792 Z_scripterrlog("%s Script %s attempted to %s an invalid jump to (%d).\n", type_str, comboscriptmap[i].scriptname.c_str(), opname, sarg1); break;
23793
23794 default: break;
23795 }
23796 }
23797
23798 95238 static void script_exit_cleanup(bool no_dealloc)
23799 {
23800 95238 ScriptType type = curScriptType;
23801 95238 word script = curScriptNum;
23802 95238 int32_t i = curScriptIndex;
23803
23804
7/8
✓ Branch 0 taken 17121 times.
✓ Branch 1 taken 64858 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11015 times.
✓ Branch 4 taken 106 times.
✓ Branch 5 taken 49 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 2079 times.
95238 switch(type)
23805 {
23806 case ScriptType::FFC:
23807 {
23808
1/2
✓ Branch 0 taken 11015 times.
✗ Branch 1 not taken.
11015 if (auto ffc = ResolveFFCWithID(i))
23809 11015 ffc->script = 0;
23810 11015 auto& data = get_script_engine_data(type, i);
23811 11015 data.doscript = false;
23812 11015 data.clear_ref();
23813 }
23814 11015 break;
23815
23816 case ScriptType::Screen:
23817 106 get_scr(i)->script = 0;
23818 case ScriptType::Global:
23819 case ScriptType::Hero:
23820 case ScriptType::DMap:
23821 case ScriptType::OnMap:
23822 case ScriptType::ScriptedActiveSubscreen:
23823 case ScriptType::ScriptedPassiveSubscreen:
23824 case ScriptType::EngineSubscreen:
23825 case ScriptType::Combo:
23826 {
23827 17227 auto& data = get_script_engine_data(type, i);
23828 17227 data.doscript = false;
23829 17227 data.clear_ref();
23830 }
23831 17227 break;
23832 case ScriptType::Ewpn:
23833 case ScriptType::Lwpn:
23834 case ScriptType::NPC:
23835 case ScriptType::ItemSprite:
23836 {
23837 64858 auto& data = get_script_engine_data(type, i);
23838 64858 data.doscript = false;
23839 64858 data.clear_ref();
23840
1/2
✓ Branch 0 taken 64858 times.
✗ Branch 1 not taken.
64858 if (auto spr = sprite::getByUID(i))
23841 64858 spr->script = 0;
23842 }
23843 64858 break;
23844
23845 case ScriptType::Generic:
23846 49 user_genscript::get(script).quit();
23847 49 break;
23848
23849 case ScriptType::GenericFrozen:
23850 {
23851 // TODO use `i`?
23852 10 auto& data = get_script_engine_data(type, gen_frozen_index-1);
23853 10 data.doscript = false;
23854 10 data.clear_ref();
23855 10 break;
23856 }
23857
23858 case ScriptType::Item:
23859 {
23860
2/2
✓ Branch 0 taken 1742 times.
✓ Branch 1 taken 337 times.
2079 bool collect = ( ( i < 1 ) || (i == COLLECT_SCRIPT_ITEM_ZERO) );
23861 2079 auto& data = get_script_engine_data(type, i);
23862
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 1742 times.
2079 if ( !collect )
23863 {
23864
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1742 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1742 if ( (itemsbuf[i].flags&item_passive_script) && game->item[i] ) itemsbuf[i].script = 0; //Quit perpetual scripts, too.
23865 1742 }
23866 2079 data.doscript = 0;
23867 2079 data.clear_ref();
23868 2079 break;
23869 }
23870 }
23871
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95238 times.
95238 if(!no_dealloc)
23872
2/2
✓ Branch 0 taken 93159 times.
✓ Branch 1 taken 2079 times.
95238 switch(type)
23873 {
23874 case ScriptType::Item:
23875 {
23876
2/2
✓ Branch 0 taken 1742 times.
✓ Branch 1 taken 337 times.
2079 bool collect = ( ( i < 1 ) || (i == COLLECT_SCRIPT_ITEM_ZERO) );
23877
3/4
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 1742 times.
✓ Branch 2 taken 337 times.
✗ Branch 3 not taken.
2079 int new_i = ( collect ) ? (( i != COLLECT_SCRIPT_ITEM_ZERO ) ? (i * -1) : 0) : i;
23878 2079 FFScript::deallocateAllScriptOwned(type, new_i);
23879 2079 break;
23880 }
23881
23882 default:
23883 93159 FFScript::deallocateAllScriptOwned(type, i);
23884 93159 break;
23885 95238 }
23886 95238 }
23887
23888 39186518 int32_t run_script(ScriptType type, word script, int32_t i)
23889 {
23890
3/4
✓ Branch 0 taken 39186518 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 39186418 times.
39186518 if(Quit==qRESET || Quit==qEXIT) // In case an earlier script hung
23891 100 return RUNSCRIPT_ERROR;
23892
23893
4/4
✓ Branch 0 taken 26861833 times.
✓ Branch 1 taken 12324585 times.
✓ Branch 2 taken 4459422 times.
✓ Branch 3 taken 22402411 times.
39186418 if(type != ScriptType::Global && !script) return RUNSCRIPT_OK; //Safeguard against running null scripts
23894
23895 34726996 combopos_modified = -1;
23896 34726996 curScriptType=type;
23897 34726996 curScriptNum=script;
23898 34726996 curScriptIndex=i;
23899 34726996 current_zasm_register=0;
23900 //numInstructions=0; //DON'T CLEAR THIS OR IT CAN HARDLOCK! -Em
23901
23902
2/4
✓ Branch 0 taken 34726996 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34726996 times.
34726996 if (!(type >= ScriptType::First && type <= ScriptType::Last))
23903 {
23904 al_trace("Invalid script type: %d\n", (int)type);
23905 return RUNSCRIPT_ERROR;
23906 }
23907
23908 34726996 auto& data = get_script_engine_data(type, i);
23909 34726996 set_current_script_engine_data(data, type, script, i);
23910
23911 // Because qst.cpp likes to write script_data without setting this.
23912 34726996 curscript->meta.script_type = type;
23913
23914 // If script isn't valid, we don't have a `pc` to start from... just exit.
23915
2/2
✓ Branch 0 taken 34724108 times.
✓ Branch 1 taken 2888 times.
34726996 if(!curscript->valid())
23916 {
23917 2888 script_exit_cleanup(false);
23918 2888 return RUNSCRIPT_OK;
23919 }
23920
23921 34724108 script_funcrun = false;
23922
23923 34724108 JittedScriptInstance* j_instance = nullptr;
23924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34724108 times.
34724108 if (jit_is_enabled())
23925 {
23926 34724108 auto& data = get_script_engine_data(type, i);
23927
2/2
✓ Branch 0 taken 34599857 times.
✓ Branch 1 taken 124251 times.
34724108 if (!data.j_instance)
23928 124251 data.j_instance = std::shared_ptr<JittedScriptInstance>(jit_create_script_instance(curscript, ri));
23929 34724108 j_instance = data.j_instance.get();
23930 34724108 }
23931
23932 34724108 runtime_script_debug_handle = nullptr;
23933
1/2
✓ Branch 0 taken 34724108 times.
✗ Branch 1 not taken.
34724108 if (script_debug_is_runtime_debugging())
23934 {
23935 if (!script_debug_handles.contains(curscript->id))
23936 {
23937 script_debug_handles.emplace(curscript->id, ScriptDebugHandle(
23938 curscript->zasm_script.get(), ScriptDebugHandle::OutputSplit::ByFrame, curscript->name()));
23939 }
23940 runtime_script_debug_handle = &script_debug_handles.at(curscript->id);
23941 runtime_script_debug_handle->update_file();
23942 std::string line = fmt::format("=== running script type: {} index: {} name: {} i: {} script: {}", ScriptTypeToString(curscript->id.type), curscript->id.index, curscript->meta.script_name, i, script);
23943 runtime_script_debug_handle->print("\n");
23944 runtime_script_debug_handle->print(line.c_str());
23945 runtime_script_debug_handle->print("\n");
23946
23947 replay_step_comment(line);
23948 }
23949
1/2
✓ Branch 0 taken 34724108 times.
✗ Branch 1 not taken.
34724108 if (script_debug_is_runtime_debugging() == 1)
23950 {
23951 std::string line = script_debug_registers_and_stack_to_string();
23952 runtime_script_debug_handle->print(line.c_str());
23953 runtime_script_debug_handle->print("\n");
23954
23955 util::replchar(line, '\n', ' ');
23956 replay_step_comment(line);
23957 }
23958
23959 int32_t result;
23960
2/2
✓ Branch 0 taken 34722819 times.
✓ Branch 1 taken 1289 times.
34724108 if (j_instance)
23961 {
23962
2/2
✓ Branch 0 taken 70511 times.
✓ Branch 1 taken 34652308 times.
34722819 if (ri->waitframes)
23963 {
23964 70511 --ri->waitframes;
23965 70511 result = RUNSCRIPT_OK;
23966 70511 }
23967 else
23968 {
23969 // Retain the script instance because if deleted while running, terrible things can happen (crash),
23970 // as the jit runtimes often write to it. Typically a script won't delete its own script handle,
23971 // but scripts can run nested, so lets capture a temporary retaining reference as part of the
23972 // call stack.
23973 34652308 auto retainer = data.j_instance;
23974
1/2
✓ Branch 0 taken 34652308 times.
✗ Branch 1 not taken.
34652308 result = jit_run_script(j_instance);
23975
23976
4/4
✓ Branch 0 taken 34652306 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 34652304 times.
34652308 if (result == RUNSCRIPT_JIT_STACK_OVERFLOW || result == RUNSCRIPT_JIT_CALL_LIMIT)
23977 {
23978 4 ri->overflow = true;
23979
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (result == RUNSCRIPT_JIT_STACK_OVERFLOW)
23980
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 log_stack_overflow_error();
23981 else
23982
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 log_call_limit_error();
23983
23984
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if (!(script_funcrun && curscript->meta.ffscript_v < 23))
23985 {
23986
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 script_exit_cleanup(false);
23987 4 result = RUNSCRIPT_STOPPED;
23988 4 }
23989 else
23990 {
23991 result = RUNSCRIPT_OK;
23992 }
23993 4 }
23994 34652308 }
23995 34722819 }
23996 else
23997 {
23998 1289 result = run_script_int();
23999 }
24000
24001
2/2
✓ Branch 0 taken 24326322 times.
✓ Branch 1 taken 10397786 times.
34724108 if (ZScriptVersion::gc())
24002 {
24003 // Drain the autorelease pool.
24004 // Move the vector, since destructors can possibly
24005 // create objects and modify `script_object_autorelease_pool`.
24006 10397786 auto ids = std::move(script_object_autorelease_pool);
24007
2/2
✓ Branch 0 taken 10397786 times.
✓ Branch 1 taken 53643 times.
10451429 for (auto id : ids)
24008
1/2
✓ Branch 0 taken 53643 times.
✗ Branch 1 not taken.
53643 script_object_ref_dec(id);
24009
24010 // This throttles the actual full GC run.
24011
1/2
✓ Branch 0 taken 10397786 times.
✗ Branch 1 not taken.
10397786 maybe_run_gc();
24012 10397786 }
24013
24014
6/16
✗ Branch 0 not taken.
✓ Branch 1 taken 34724108 times.
✓ Branch 2 taken 34724108 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 34724108 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 34724108 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34724108 times.
✓ Branch 10 taken 34724108 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
69448216 if (replay_is_active() && replay_get_meta_bool("debug_script_state"))
24015 {
24016 std::string str = script_debug_registers_and_stack_to_string();
24017 util::replstr(str, "\n", " ");
24018 replay_step_comment(str);
24019 }
24020
24021
1/2
✓ Branch 0 taken 34724108 times.
✗ Branch 1 not taken.
34724108 if (runtime_script_debug_handle)
24022 {
24023 runtime_script_debug_handle->print(fmt::format("result: {}\n", result).c_str());
24024 replay_step_comment(fmt::format("result: {}", result));
24025 }
24026 34724108 return result;
24027 39186518 }
24028
24029 // Run [count] number of commands (unless something errors).
24030 7437964 int32_t run_script_jit_sequence(JittedScriptInstance* j_instance, int32_t pc, uint32_t sp, int32_t count)
24031 {
24032 7437964 ri->pc = pc;
24033 7437964 ri->sp = sp;
24034 7437964 j_instance->uncompiled_command_count = count;
24035 7437964 j_instance->sequence_mode = true;
24036 7437964 j_instance->should_wait = false;
24037 7437964 int r = run_script_int(j_instance);
24038
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 7437953 times.
7437964 if (r != RUNSCRIPT_OK)
24039 11 return r;
24040
24041 7437953 return j_instance->should_wait ? RUNSCRIPT_STOPPED : RUNSCRIPT_OK;
24042 7437964 }
24043
24044 // Run a single command.
24045 1361917579 int32_t run_script_jit_one(JittedScriptInstance* j_instance, int32_t pc, uint32_t sp)
24046 {
24047 1361917579 ri->pc = pc;
24048 1361917579 ri->sp = sp;
24049 1361917579 j_instance->uncompiled_command_count = 1;
24050 1361917579 j_instance->sequence_mode = true;
24051 1361917579 j_instance->should_wait = false;
24052 1361917579 int r = run_script_int(j_instance);
24053
2/2
✓ Branch 0 taken 95653 times.
✓ Branch 1 taken 1361821926 times.
1361917579 if (r != RUNSCRIPT_OK)
24054 95653 return r;
24055
24056 1361821926 return j_instance->should_wait ? RUNSCRIPT_STOPPED : RUNSCRIPT_OK;
24057 1361917579 }
24058
24059 // Runs the script until the next function call, return, wait frame, or error.
24060 1427069 int32_t run_script_jit_until_call_or_return(JittedScriptInstance* j_instance, int32_t pc, uint32_t sp)
24061 {
24062 1427069 ri->pc = pc;
24063 1427069 ri->sp = sp;
24064 1427069 j_instance->uncompiled_command_count = -1;
24065 1427069 j_instance->sequence_mode = false;
24066 1427069 j_instance->should_wait = false;
24067 1427069 int r = run_script_int(j_instance);
24068
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 1426437 times.
1427069 if (r != RUNSCRIPT_OK)
24069 632 return r;
24070
24071 1426437 return j_instance->should_wait ? RUNSCRIPT_STOPPED : RUNSCRIPT_OK;
24072 1427069 }
24073
24074 // When j_instance is null, that means the interperter is fully in charge.
24075 // Otherwise, the JIT may still call this function for the many commands that are not compiled, or
24076 // during the period before a function is "hot" enough to have been compiled.
24077 1370784711 int32_t run_script_int(JittedScriptInstance* j_instance)
24078 {
24079 1370784711 bool is_jitted = j_instance;
24080 1370784711 ScriptType type = curScriptType;
24081 1370784711 word script = curScriptNum;
24082 1370784711 int32_t i = curScriptIndex;
24083
24084 1370784711 current_zasm_command=(ASM_DEFINE)0; // this is actually SETV, but we never will print that as a context string, so it's fine.
24085
24086 1370784711 int commands_run = 0;
24087
2/2
✓ Branch 0 taken 1370783901 times.
✓ Branch 1 taken 810 times.
1370784711 bool old_script_funcrun = script_funcrun && curscript->meta.ffscript_v < 23;
24088
2/2
✓ Branch 0 taken 1370782612 times.
✓ Branch 1 taken 2099 times.
1370784711 if(!is_jitted)
24089 {
24090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2099 times.
2099 if(ri->waitframes)
24091 {
24092 --ri->waitframes;
24093 return RUNSCRIPT_OK;
24094 }
24095 2099 zs_vargs.clear();
24096
24097 #ifdef _FFDISSASSEMBLY
24098
24099 if(curscript->zasm[ri->pc].command != 0xFFFF)
24100 {
24101 #ifdef _FFONESCRIPTDISSASSEMBLY
24102 zc_trace_clear();
24103 #endif
24104
24105 switch(type)
24106 {
24107 case ScriptType::FFC:
24108 al_trace("\nStart of FFC script %i processing on FFC %i:\n", script, i);
24109 break;
24110
24111 case ScriptType::Item:
24112 al_trace("\nStart of item script %i processing:\n", script);
24113 break;
24114
24115 case ScriptType::Global:
24116 al_trace("\nStart of global script %I processing:\n", script);
24117 break;
24118 }
24119 }
24120
24121 #endif
24122 2099 }
24123
24124 // This is used to help debug differences w/ the JIT implementation. See scripts/jit_runtime_debug.py.
24125 1370784711 bool is_debugging = script_debug_is_runtime_debugging() == 2;
24126 1370784711 bool increment = true;
24127
5/8
✓ Branch 0 taken 235 times.
✓ Branch 1 taken 1370784476 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 235 times.
✓ Branch 4 taken 235 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 235 times.
✗ Branch 7 not taken.
1370784711 static std::vector<ffscript> empty_zasm = {{0xFFFF}};
24128
1/2
✓ Branch 0 taken 1370784711 times.
✗ Branch 1 not taken.
1370784711 const auto& zasm = curscript->valid() ? curscript->zasm_script->zasm : empty_zasm;
24129 1370784711 word scommand = zasm[ri->pc].command;
24130 1370784711 bool hit_invalid_zasm = false;
24131 1370784711 bool no_dealloc = false;
24132
2/2
✓ Branch 0 taken 1445 times.
✓ Branch 1 taken 1566909827 times.
1566911272 while(scommand != 0xFFFF)
24133 {
24134 1566909827 const auto& op = zasm[ri->pc];
24135 1566909827 scommand = op.command;
24136 1566909827 sarg1 = op.arg1;
24137 1566909827 sarg2 = op.arg2;
24138 1566909827 sarg3 = op.arg3;
24139 1566909827 sargstr = op.strptr;
24140 1566909827 sargvec = op.vecptr;
24141
24142 1566909827 current_zasm_command = (ASM_DEFINE)scommand;
24143
24144
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1566909827 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1566909827 if (is_debugging && (!is_jitted || !j_instance->sequence_mode || commands_run > 0))
24145 {
24146 runtime_script_debug_handle->pre_command();
24147 }
24148
24149 1566909827 bool waiting = true;
24150
6/6
✓ Branch 0 taken 1532351766 times.
✓ Branch 1 taken 6654034 times.
✓ Branch 2 taken 2935193 times.
✓ Branch 3 taken 3500 times.
✓ Branch 4 taken 24957699 times.
✓ Branch 5 taken 7635 times.
1566909827 switch(scommand) //Handle waitframe-type commands first
24151 {
24152 case WAITDRAW:
24153 {
24154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6654034 times.
6654034 if(script_funcrun)
24155 scommand = NOP;
24156
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 6654034 times.
✗ Branch 2 not taken.
6654034 else switch(type)
24157 {
24158 case ScriptType::EngineSubscreen: //ignore waitdraws
24159 Z_scripterrlog("'Waitdraw()' is invalid in subscreen scripts, will be ignored\n");
24160 scommand = NOP;
24161 break;
24162 case ScriptType::Generic:
24163 case ScriptType::GenericFrozen: //ignore waitdraws
24164 Z_scripterrlog("'Waitdraw()' is invalid in generic scripts, will be ignored\n");
24165 scommand = NOP;
24166 break;
24167 }
24168 6654034 break;
24169 }
24170 case WAITTO:
24171 {
24172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2935193 times.
2935193 if(script_funcrun)
24173 scommand = NOP;
24174
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 2935193 times.
2935193 else switch(type)
24175 {
24176 case ScriptType::GenericFrozen:
24177 //ignore, no warn/error
24178 scommand = NOP;
24179 break;
24180 case ScriptType::Generic:
24181 {
24182 2935193 user_genscript& scr = user_genscript::get(script);
24183 2935193 int32_t target = get_register(sarg1)/10000L;
24184 2935193 bool atleast = get_register(sarg2)!=0;
24185
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2935193 times.
2935193 if(unsigned(target) > SCR_TIMING_END_FRAME)
24186 {
24187 Z_scripterrlog("Invalid value '%d' provided to 'WaitTo()'\n", target);
24188 scommand = NOP;
24189 break;
24190 }
24191
2/4
✓ Branch 0 taken 2935164 times.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2935193 if(genscript_timing == target ||
24192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2935164 times.
2935164 (atleast && genscript_timing < target))
24193 {
24194 //Already that time, skip the command
24195 29 scommand = NOP;
24196 29 break;
24197 }
24198 2935164 scr.waituntil = scr_timing(target);
24199 2935164 scr.wait_atleast = atleast;
24200 2935164 break;
24201 }
24202 default:
24203 Z_scripterrlog("'WaitTo()' is only valid in 'generic' scripts!\n");
24204 scommand = NOP;
24205 break;
24206 }
24207 2935193 break;
24208 }
24209 case WAITEVENT:
24210 {
24211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3500 times.
3500 if(script_funcrun)
24212 scommand = NOP;
24213
1/3
✓ Branch 0 taken 3500 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
3500 else switch(type)
24214 {
24215 case ScriptType::GenericFrozen:
24216 scommand = WAITFRAME;
24217 ri->d[0] = GENSCR_EVENT_NIL*10000; //no event
24218 break;
24219 case ScriptType::Generic:
24220 {
24221 3500 user_genscript& scr = user_genscript::get(script);
24222 3500 scr.waitevent = true;
24223 3500 break;
24224 }
24225 default:
24226 Z_scripterrlog("'WaitEvent()' is only valid in 'generic' scripts!\n");
24227 scommand = NOP;
24228 break;
24229 }
24230 3500 break;
24231 }
24232 case WAITFRAME:
24233 {
24234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24957699 times.
24957699 if(script_funcrun)
24235 scommand = NOP;
24236
2/2
✓ Branch 0 taken 21839252 times.
✓ Branch 1 taken 3118447 times.
24957699 else switch(type)
24237 {
24238 case ScriptType::Generic:
24239 {
24240 3118447 user_genscript& scr = user_genscript::get(script);
24241 3118447 scr.waituntil = SCR_TIMING_START_FRAME;
24242 3118447 scr.wait_atleast = false;
24243 3118447 break;
24244 }
24245 }
24246 24957699 break;
24247 }
24248 case WAITFRAMESR:
24249 {
24250 7635 auto count = get_register(sarg1);
24251
3/4
✓ Branch 0 taken 7635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 760 times.
✓ Branch 3 taken 6875 times.
7635 if(script_funcrun || count <= 0)
24252 {
24253 760 scommand = NOP;
24254 760 break;
24255 }
24256 6875 auto frames = count/10000;
24257
1/2
✓ Branch 0 taken 6875 times.
✗ Branch 1 not taken.
6875 if(count%10000) ++frames; //round up decimals
24258 6875 ri->waitframes = frames-1; //this frame doesn't count
24259
2/2
✓ Branch 0 taken 6562 times.
✓ Branch 1 taken 313 times.
6875 switch(type)
24260 {
24261 case ScriptType::Generic:
24262 {
24263 313 user_genscript& scr = user_genscript::get(script);
24264 313 scr.waituntil = SCR_TIMING_START_FRAME;
24265 313 scr.wait_atleast = false;
24266 313 break;
24267 }
24268 }
24269 6875 break;
24270 }
24271 1532351766 default: waiting = false;
24272 1532351766 }
24273
4/4
✓ Branch 0 taken 34558061 times.
✓ Branch 1 taken 1532351766 times.
✓ Branch 2 taken 789 times.
✓ Branch 3 taken 34557272 times.
1566909827 if(waiting && scommand != NOP)
24274 {
24275
2/2
✓ Branch 0 taken 1286 times.
✓ Branch 1 taken 34555986 times.
34557272 if (is_jitted)
24276 34555986 j_instance->should_wait = true;
24277 34557272 break;
24278 }
24279
24280 1532352555 numInstructions++;
24281
2/2
✓ Branch 0 taken 1530820282 times.
✓ Branch 1 taken 1532273 times.
1532352555 if(numInstructions==hangcount) // No need to check frequently
24282 {
24283 1532273 numInstructions=0;
24284 1532273 poll_keyboard();
24285 1532273 checkQuitKeys();
24286
1/2
✓ Branch 0 taken 1532273 times.
✗ Branch 1 not taken.
1532273 if(Quit)
24287 scommand=0xFFFF;
24288 1532273 }
24289
24290
242/591
✗ Branch 0 not taken.
✓ Branch 1 taken 1407410 times.
✓ Branch 2 taken 1408606 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 52004397 times.
✓ Branch 6 taken 89949202 times.
✓ Branch 7 taken 7651728 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 5663787 times.
✓ Branch 11 taken 20510595 times.
✓ Branch 12 taken 825385 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 20119254 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 10 times.
✓ Branch 23 taken 2819285 times.
✓ Branch 24 taken 2018844 times.
✓ Branch 25 taken 6680540 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 3916 times.
✓ Branch 28 taken 5902190 times.
✓ Branch 29 taken 18404 times.
✓ Branch 30 taken 250385 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 980737 times.
✓ Branch 33 taken 2 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✓ Branch 37 taken 14 times.
✓ Branch 38 taken 56 times.
✓ Branch 39 taken 935 times.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✓ Branch 43 taken 4636 times.
✓ Branch 44 taken 137138 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 906 times.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✓ Branch 51 taken 9100 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 8306 times.
✓ Branch 54 taken 1570475 times.
✓ Branch 55 taken 602347 times.
✓ Branch 56 taken 1820491 times.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✓ Branch 59 taken 15 times.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✓ Branch 65 taken 10744 times.
✓ Branch 66 taken 34296 times.
✗ Branch 67 not taken.
✓ Branch 68 taken 12533 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 34 times.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✓ Branch 74 taken 22 times.
✓ Branch 75 taken 2 times.
✓ Branch 76 taken 1383 times.
✓ Branch 77 taken 11645 times.
✓ Branch 78 taken 12284 times.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✓ Branch 81 taken 123 times.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✓ Branch 85 taken 1 times.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✓ Branch 91 taken 1351 times.
✓ Branch 92 taken 5661515 times.
✓ Branch 93 taken 585769 times.
✓ Branch 94 taken 58103417 times.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✓ Branch 98 taken 370 times.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✓ Branch 101 taken 4781 times.
✓ Branch 102 taken 234 times.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✓ Branch 109 taken 54 times.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✓ Branch 112 taken 18 times.
✗ Branch 113 not taken.
✓ Branch 114 taken 598 times.
✗ Branch 115 not taken.
✓ Branch 116 taken 166704 times.
✗ Branch 117 not taken.
✓ Branch 118 taken 303017 times.
✗ Branch 119 not taken.
✓ Branch 120 taken 31517 times.
✓ Branch 121 taken 8420 times.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✓ Branch 126 taken 296065 times.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✓ Branch 129 taken 5 times.
✓ Branch 130 taken 3 times.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✓ Branch 134 taken 40 times.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 148 not taken.
✓ Branch 149 taken 3 times.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✓ Branch 156 taken 73 times.
✓ Branch 157 taken 137138 times.
✗ Branch 158 not taken.
✓ Branch 159 taken 3237076 times.
✓ Branch 160 taken 65124359 times.
✓ Branch 161 taken 53527326 times.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✓ Branch 164 taken 6689206 times.
✓ Branch 165 taken 3 times.
✓ Branch 166 taken 92288 times.
✓ Branch 167 taken 68195451 times.
✓ Branch 168 taken 2951053 times.
✗ Branch 169 not taken.
✓ Branch 170 taken 593 times.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✓ Branch 174 taken 6863262 times.
✓ Branch 175 taken 534062 times.
✓ Branch 176 taken 1667257 times.
✓ Branch 177 taken 1650331 times.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✓ Branch 180 taken 1008261 times.
✓ Branch 181 taken 112218 times.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✓ Branch 184 taken 212470599 times.
✓ Branch 185 taken 104059060 times.
✗ Branch 186 not taken.
✓ Branch 187 taken 2984544 times.
✓ Branch 188 taken 3274079 times.
✓ Branch 189 taken 569712 times.
✗ Branch 190 not taken.
✓ Branch 191 taken 3148656 times.
✗ Branch 192 not taken.
✓ Branch 193 taken 10564123 times.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✓ Branch 196 taken 20713642 times.
✓ Branch 197 taken 207868 times.
✓ Branch 198 taken 48376 times.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✓ Branch 202 taken 3465034 times.
✗ Branch 203 not taken.
✓ Branch 204 taken 3202 times.
✗ Branch 205 not taken.
✓ Branch 206 taken 14188523 times.
✓ Branch 207 taken 1621 times.
✗ Branch 208 not taken.
✓ Branch 209 taken 13664241 times.
✗ Branch 210 not taken.
✓ Branch 211 taken 303089179 times.
✓ Branch 212 taken 10105657 times.
✓ Branch 213 taken 80 times.
✓ Branch 214 taken 3358372 times.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✓ Branch 218 taken 73824 times.
✓ Branch 219 taken 6 times.
✓ Branch 220 taken 141873 times.
✓ Branch 221 taken 3162 times.
✓ Branch 222 taken 269043 times.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✓ Branch 225 taken 25681 times.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✓ Branch 228 taken 42273 times.
✗ Branch 229 not taken.
✓ Branch 230 taken 9768934 times.
✗ Branch 231 not taken.
✓ Branch 232 taken 100 times.
✓ Branch 233 taken 196070 times.
✓ Branch 234 taken 17252 times.
✓ Branch 235 taken 14918 times.
✗ Branch 236 not taken.
✓ Branch 237 taken 32282 times.
✗ Branch 238 not taken.
✓ Branch 239 taken 16 times.
✓ Branch 240 taken 2544 times.
✗ Branch 241 not taken.
✓ Branch 242 taken 14127 times.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✓ Branch 249 taken 4797 times.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✗ Branch 252 not taken.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✓ Branch 257 taken 2 times.
✗ Branch 258 not taken.
✓ Branch 259 taken 234 times.
✓ Branch 260 taken 7914 times.
✗ Branch 261 not taken.
✗ Branch 262 not taken.
✓ Branch 263 taken 115 times.
✗ Branch 264 not taken.
✗ Branch 265 not taken.
✓ Branch 266 taken 2170 times.
✗ Branch 267 not taken.
✓ Branch 268 taken 1332 times.
✓ Branch 269 taken 13037 times.
✓ Branch 270 taken 162607 times.
✓ Branch 271 taken 30 times.
✓ Branch 272 taken 3523313 times.
✓ Branch 273 taken 2674 times.
✗ Branch 274 not taken.
✓ Branch 275 taken 2918055 times.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✓ Branch 279 taken 10089782 times.
✓ Branch 280 taken 6556 times.
✗ Branch 281 not taken.
✗ Branch 282 not taken.
✗ Branch 283 not taken.
✓ Branch 284 taken 969 times.
✓ Branch 285 taken 648 times.
✓ Branch 286 taken 165132 times.
✗ Branch 287 not taken.
✓ Branch 288 taken 4411 times.
✗ Branch 289 not taken.
✓ Branch 290 taken 678025 times.
✓ Branch 291 taken 249892 times.
✗ Branch 292 not taken.
✗ Branch 293 not taken.
✗ Branch 294 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 297 not taken.
✓ Branch 298 taken 3719887 times.
✓ Branch 299 taken 80068802 times.
✓ Branch 300 taken 4965499 times.
✓ Branch 301 taken 27016621 times.
✓ Branch 302 taken 4974468 times.
✓ Branch 303 taken 352043 times.
✗ Branch 304 not taken.
✗ Branch 305 not taken.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✓ Branch 308 taken 4 times.
✓ Branch 309 taken 317888 times.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✗ Branch 312 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✓ Branch 318 taken 3 times.
✓ Branch 319 taken 287 times.
✓ Branch 320 taken 33594 times.
✗ Branch 321 not taken.
✓ Branch 322 taken 15 times.
✓ Branch 323 taken 3 times.
✗ Branch 324 not taken.
✗ Branch 325 not taken.
✓ Branch 326 taken 127 times.
✗ Branch 327 not taken.
✓ Branch 328 taken 5660 times.
✗ Branch 329 not taken.
✓ Branch 330 taken 5436 times.
✗ Branch 331 not taken.
✓ Branch 332 taken 427914 times.
✗ Branch 333 not taken.
✗ Branch 334 not taken.
✓ Branch 335 taken 2004 times.
✓ Branch 336 taken 63830 times.
✗ Branch 337 not taken.
✓ Branch 338 taken 357 times.
✓ Branch 339 taken 236 times.
✓ Branch 340 taken 140 times.
✓ Branch 341 taken 3807 times.
✗ Branch 342 not taken.
✗ Branch 343 not taken.
✗ Branch 344 not taken.
✗ Branch 345 not taken.
✓ Branch 346 taken 14 times.
✗ Branch 347 not taken.
✗ Branch 348 not taken.
✗ Branch 349 not taken.
✗ Branch 350 not taken.
✓ Branch 351 taken 2768 times.
✓ Branch 352 taken 1860392 times.
✗ Branch 353 not taken.
✗ Branch 354 not taken.
✗ Branch 355 not taken.
✗ Branch 356 not taken.
✗ Branch 357 not taken.
✓ Branch 358 taken 6366 times.
✓ Branch 359 taken 6042586 times.
✗ Branch 360 not taken.
✓ Branch 361 taken 3585254 times.
✗ Branch 362 not taken.
✗ Branch 363 not taken.
✓ Branch 364 taken 182518 times.
✗ Branch 365 not taken.
✓ Branch 366 taken 5603 times.
✗ Branch 367 not taken.
✓ Branch 368 taken 10 times.
✗ Branch 369 not taken.
✓ Branch 370 taken 223 times.
✓ Branch 371 taken 11 times.
✗ Branch 372 not taken.
✗ Branch 373 not taken.
✓ Branch 374 taken 11 times.
✗ Branch 375 not taken.
✗ Branch 376 not taken.
✓ Branch 377 taken 24 times.
✓ Branch 378 taken 87 times.
✓ Branch 379 taken 92 times.
✗ Branch 380 not taken.
✗ Branch 381 not taken.
✗ Branch 382 not taken.
✓ Branch 383 taken 31 times.
✗ Branch 384 not taken.
✓ Branch 385 taken 1064 times.
✓ Branch 386 taken 130 times.
✗ Branch 387 not taken.
✗ Branch 388 not taken.
✗ Branch 389 not taken.
✓ Branch 390 taken 450 times.
✗ Branch 391 not taken.
✓ Branch 392 taken 112 times.
✗ Branch 393 not taken.
✓ Branch 394 taken 932 times.
✓ Branch 395 taken 53 times.
✗ Branch 396 not taken.
✗ Branch 397 not taken.
✗ Branch 398 not taken.
✗ Branch 399 not taken.
✗ Branch 400 not taken.
✗ Branch 401 not taken.
✗ Branch 402 not taken.
✗ Branch 403 not taken.
✗ Branch 404 not taken.
✗ Branch 405 not taken.
✓ Branch 406 taken 14 times.
✗ Branch 407 not taken.
✓ Branch 408 taken 52 times.
✗ Branch 409 not taken.
✓ Branch 410 taken 12 times.
✗ Branch 411 not taken.
✓ Branch 412 taken 32179028 times.
✗ Branch 413 not taken.
✓ Branch 414 taken 22558 times.
✓ Branch 415 taken 3593 times.
✗ Branch 416 not taken.
✓ Branch 417 taken 601509 times.
✓ Branch 418 taken 117 times.
✓ Branch 419 taken 11796078 times.
✓ Branch 420 taken 1279180 times.
✓ Branch 421 taken 176099 times.
✗ Branch 422 not taken.
✓ Branch 423 taken 20064 times.
✗ Branch 424 not taken.
✗ Branch 425 not taken.
✓ Branch 426 taken 25461489 times.
✗ Branch 427 not taken.
✗ Branch 428 not taken.
✓ Branch 429 taken 257 times.
✓ Branch 430 taken 364895 times.
✗ Branch 431 not taken.
✓ Branch 432 taken 364942 times.
✓ Branch 433 taken 50 times.
✓ Branch 434 taken 3 times.
✓ Branch 435 taken 13670631 times.
✓ Branch 436 taken 18282859 times.
✓ Branch 437 taken 382 times.
✓ Branch 438 taken 118 times.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✓ Branch 441 taken 3182 times.
✗ Branch 442 not taken.
✗ Branch 443 not taken.
✗ Branch 444 not taken.
✗ Branch 445 not taken.
✓ Branch 446 taken 26757 times.
✓ Branch 447 taken 3512 times.
✓ Branch 448 taken 146 times.
✗ Branch 449 not taken.
✗ Branch 450 not taken.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✗ Branch 453 not taken.
✗ Branch 454 not taken.
✗ Branch 455 not taken.
✗ Branch 456 not taken.
✗ Branch 457 not taken.
✗ Branch 458 not taken.
✓ Branch 459 taken 49289145 times.
✗ Branch 460 not taken.
✗ Branch 461 not taken.
✗ Branch 462 not taken.
✗ Branch 463 not taken.
✓ Branch 464 taken 10 times.
✗ Branch 465 not taken.
✗ Branch 466 not taken.
✗ Branch 467 not taken.
✓ Branch 468 taken 57032 times.
✗ Branch 469 not taken.
✗ Branch 470 not taken.
✗ Branch 471 not taken.
✗ Branch 472 not taken.
✗ Branch 473 not taken.
✗ Branch 474 not taken.
✗ Branch 475 not taken.
✗ Branch 476 not taken.
✓ Branch 477 taken 7084216 times.
✓ Branch 478 taken 4 times.
✓ Branch 479 taken 9 times.
✓ Branch 480 taken 11953 times.
✓ Branch 481 taken 2 times.
✗ Branch 482 not taken.
✓ Branch 483 taken 30 times.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✗ Branch 486 not taken.
✗ Branch 487 not taken.
✗ Branch 488 not taken.
✗ Branch 489 not taken.
✗ Branch 490 not taken.
✓ Branch 491 taken 3560 times.
✓ Branch 492 taken 66 times.
✓ Branch 493 taken 14 times.
✗ Branch 494 not taken.
✗ Branch 495 not taken.
✗ Branch 496 not taken.
✗ Branch 497 not taken.
✗ Branch 498 not taken.
✗ Branch 499 not taken.
✗ Branch 500 not taken.
✓ Branch 501 taken 100 times.
✓ Branch 502 taken 1798 times.
✓ Branch 503 taken 3596 times.
✗ Branch 504 not taken.
✗ Branch 505 not taken.
✓ Branch 506 taken 440764 times.
✗ Branch 507 not taken.
✗ Branch 508 not taken.
✗ Branch 509 not taken.
✗ Branch 510 not taken.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 513 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 516 not taken.
✗ Branch 517 not taken.
✗ Branch 518 not taken.
✗ Branch 519 not taken.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✗ Branch 522 not taken.
✗ Branch 523 not taken.
✓ Branch 524 taken 15 times.
✗ Branch 525 not taken.
✓ Branch 526 taken 2511 times.
✓ Branch 527 taken 1482 times.
✗ Branch 528 not taken.
✗ Branch 529 not taken.
✗ Branch 530 not taken.
✗ Branch 531 not taken.
✓ Branch 532 taken 5 times.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✗ Branch 538 not taken.
✗ Branch 539 not taken.
✗ Branch 540 not taken.
✗ Branch 541 not taken.
✗ Branch 542 not taken.
✗ Branch 543 not taken.
✗ Branch 544 not taken.
✗ Branch 545 not taken.
✗ Branch 546 not taken.
✗ Branch 547 not taken.
✗ Branch 548 not taken.
✗ Branch 549 not taken.
✗ Branch 550 not taken.
✗ Branch 551 not taken.
✗ Branch 552 not taken.
✓ Branch 553 taken 58074 times.
✓ Branch 554 taken 463835 times.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 558 not taken.
✓ Branch 559 taken 6 times.
✓ Branch 560 taken 8 times.
✓ Branch 561 taken 10 times.
✗ Branch 562 not taken.
✗ Branch 563 not taken.
✗ Branch 564 not taken.
✗ Branch 565 not taken.
✓ Branch 566 taken 14870 times.
✓ Branch 567 taken 17877 times.
✗ Branch 568 not taken.
✗ Branch 569 not taken.
✗ Branch 570 not taken.
✗ Branch 571 not taken.
✗ Branch 572 not taken.
✓ Branch 573 taken 828 times.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 576 not taken.
✗ Branch 577 not taken.
✓ Branch 578 taken 76234 times.
✗ Branch 579 not taken.
✗ Branch 580 not taken.
✓ Branch 581 taken 1578099 times.
✗ Branch 582 not taken.
✓ Branch 583 taken 1374 times.
✓ Branch 584 taken 1578099 times.
✓ Branch 585 taken 2998 times.
✗ Branch 586 not taken.
✓ Branch 587 taken 226 times.
✓ Branch 588 taken 2427 times.
✓ Branch 589 taken 4 times.
✓ Branch 590 taken 22 times.
1532352555 switch(scommand)
24291 {
24292 //always first
24293 case 0xFFFF: //invalid command
24294 {
24295 3 const char* type_str = ScriptTypeToString(type);
24296
1/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 switch(type)
24297 {
24298 case ScriptType::FFC:
24299 zprint("%s Script %s has exited.\n", type_str, ffcmap[i].scriptname.c_str()); break;
24300 case ScriptType::NPC:
24301 zprint("%s Script %s has exited.\n", type_str, npcmap[i].scriptname.c_str()); break;
24302 case ScriptType::Lwpn:
24303 zprint("%s Script %s has exited.\n", type_str, lwpnmap[i].scriptname.c_str()); break;
24304 case ScriptType::Ewpn:
24305 zprint("%s Script %s has exited.\n", type_str, ewpnmap[i].scriptname.c_str()); break;
24306 case ScriptType::ItemSprite:
24307 zprint("%s Script %s has exited.\n", type_str, itemspritemap[i].scriptname.c_str()); break;
24308 case ScriptType::Item:
24309 zprint("%s Script %s has exited.\n", type_str, itemmap[i].scriptname.c_str()); break;
24310 case ScriptType::Global:
24311 3 zprint("%s Script %s has exited.\n", type_str, globalmap[i].scriptname.c_str()); break;
24312 case ScriptType::Hero:
24313 zprint("%s Script %s has exited.\n", type_str, playermap[i].scriptname.c_str()); break;
24314 case ScriptType::Screen:
24315 zprint("%s Script %s has exited.\n", type_str, screenmap[i].scriptname.c_str()); break;
24316 case ScriptType::OnMap:
24317 case ScriptType::DMap:
24318 case ScriptType::ScriptedActiveSubscreen:
24319 case ScriptType::ScriptedPassiveSubscreen:
24320 zprint("%s Script %s has exited.\n", type_str, dmapmap[i].scriptname.c_str()); break;
24321 case ScriptType::Combo: zprint("%s Script %s has exited.\n", type_str, comboscriptmap[i].scriptname.c_str()); break;
24322
24323 default: break;
24324 }
24325 3 break;
24326 }
24327 case QUIT:
24328 92288 scommand = 0xFFFF;
24329 92288 break;
24330 case QUIT_NO_DEALLOC:
24331 scommand = 0xFFFF;
24332 no_dealloc = true;
24333 break;
24334
24335 case NOP: //No Operation. Do nothing. -Em
24336 {
24337 // While we are here, skip many NOPs in a row to avoid the overhead
24338 // of the interpreter loop. This is especially good for how `zasm_optimize`
24339 // works, since it replaces many commands with a sequence of NOPs.
24340 // No need to do a bounds check - the last command should always be 0xFFFF.
24341
3/4
✓ Branch 0 taken 68195451 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 59591075 times.
✓ Branch 3 taken 8604376 times.
68195451 if (is_debugging || is_jitted)
24342 59591075 break;
24343
2/2
✓ Branch 0 taken 10588593 times.
✓ Branch 1 taken 8604376 times.
19192969 while (zasm[ri->pc + 1].command == NOP)
24344 10588593 ri->pc++;
24345 8604376 break;
24346 }
24347 case GOTO:
24348 {
24349
1/2
✓ Branch 0 taken 2951053 times.
✗ Branch 1 not taken.
2951053 if(sarg1 < 0 )
24350 {
24351 goto_err("GOTO");
24352 scommand = 0xFFFF;
24353 break;
24354 }
24355
24356 // When is_jitted is true, GOTO can only be processed here when j_instance->sequence_mode is false.
24357 // Track back edges (jumps to a loop head). The JIT will compiled the current
24358 // function if this is called enough.
24359
4/4
✓ Branch 0 taken 2485853 times.
✓ Branch 1 taken 465200 times.
✓ Branch 2 taken 59972 times.
✓ Branch 3 taken 2425881 times.
2951053 if (is_jitted && ri->pc > sarg1)
24360 2425881 jit_profiler_increment_function_back_edge(j_instance, sarg1);
24361
24362 2951053 ri->pc = sarg1;
24363 2951053 increment = false;
24364 2951053 break;
24365 }
24366 case GOTOR:
24367 {
24368 if(sarg1 < 0 )
24369 {
24370 goto_err("GOTOR");
24371 scommand = 0xFFFF;
24372 break;
24373 }
24374 ri->pc = (get_register(sarg1) / 10000) - 1;
24375 increment = false;
24376 }
24377 break;
24378
24379 case GOTOTRUE:
24380
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 552 times.
593 if(check_cmp(CMP_EQ))
24381 {
24382
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
552 if(sarg1 < 0 )
24383 {
24384 goto_err("GOTOTRUE");
24385 scommand = 0xFFFF;
24386 break;
24387 }
24388 552 ri->pc = sarg1;
24389 552 increment = false;
24390 552 }
24391 593 break;
24392
24393 case GOTOFALSE:
24394 if(check_cmp(CMP_NE))
24395 {
24396 if(sarg1 < 0 )
24397 {
24398 goto_err("GOTOFALSE");
24399 scommand = 0xFFFF;
24400 break;
24401 }
24402 ri->pc = sarg1;
24403 increment = false;
24404 }
24405 break;
24406
24407 case GOTOMORE:
24408 if(check_cmp(CMP_GE))
24409 {
24410 if(sarg1 < 0 )
24411 {
24412 goto_err("GOTOMORE");
24413 scommand = 0xFFFF;
24414 break;
24415 }
24416 ri->pc = sarg1;
24417 increment = false;
24418 }
24419 break;
24420
24421 case GOTOLESS:
24422 if(check_cmp(get_qr(qr_GOTOLESSNOTEQUAL) ? CMP_LT : CMP_LE))
24423 {
24424 if(sarg1 < 0 )
24425 {
24426 goto_err("GOTOLESS");
24427 scommand = 0xFFFF;
24428 break;
24429 }
24430 ri->pc = sarg1;
24431 increment = false;
24432 }
24433 break;
24434
24435 case GOTOCMP:
24436 {
24437 6863262 bool run = check_cmp(sarg2);
24438
2/2
✓ Branch 0 taken 3083320 times.
✓ Branch 1 taken 3779942 times.
6863262 if(run)
24439 {
24440
1/2
✓ Branch 0 taken 3779942 times.
✗ Branch 1 not taken.
3779942 if(sarg1 < 0 )
24441 {
24442 goto_err("GOTOCMP");
24443 scommand = 0xFFFF;
24444 break;
24445 }
24446 3779942 ri->pc = sarg1;
24447 3779942 increment = false;
24448 3779942 }
24449 6863262 break;
24450 }
24451
24452 case SETCMP:
24453 {
24454 534062 bool run = check_cmp(sarg2);
24455
2/2
✓ Branch 0 taken 526481 times.
✓ Branch 1 taken 7581 times.
534062 set_register(sarg1, run ? ((sarg2 & CMP_SETI) ? 10000 : 1) : 0);
24456 534062 break;
24457 }
24458
24459 case CALLFUNC:
24460 {
24461 1667257 retstack_push(ri->pc+1);
24462
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1667257 times.
1667257 if(sarg1 < 0 )
24463 {
24464 goto_err("CALLFUNC");
24465 scommand = 0xFFFF;
24466 break;
24467 }
24468 1667257 ri->pc = sarg1;
24469 1667257 increment = false;
24470
24471 // When is_jitted is true, CALLFUNC can only be processed here when j_instance->sequence_mode is false.
24472 // And when it is called, it marks the end of run_script_int.
24473
2/2
✓ Branch 0 taken 946572 times.
✓ Branch 1 taken 720685 times.
1667257 if (is_jitted)
24474 720685 j_instance->uncompiled_command_count = commands_run + 1;
24475 1667257 break;
24476 }
24477 case RETURNFUNC:
24478 {
24479
2/2
✓ Branch 0 taken 1649521 times.
✓ Branch 1 taken 810 times.
1650331 if(auto retpc = retstack_pop())
24480 {
24481
1/2
✓ Branch 0 taken 1649521 times.
✗ Branch 1 not taken.
1649521 if(*retpc < 0)
24482 {
24483 goto_err("RETURNFUNC");
24484 scommand = 0xFFFF;
24485 break;
24486 }
24487 1649521 ri->pc = *retpc;
24488 1649521 increment = false;
24489 1649521 }
24490 else //Returned from 'void run()', QUIT
24491 {
24492 810 scommand = 0xFFFF;
24493 }
24494
24495 // When is_jitted is true, RETURNFUNC can only be processed here when j_instance->sequence_mode is false.
24496 // And when it is called, it marks the end of run_script_int.
24497
2/2
✓ Branch 0 taken 947366 times.
✓ Branch 1 taken 702965 times.
1650331 if (is_jitted)
24498 702965 j_instance->uncompiled_command_count = commands_run + 1;
24499 1650331 break;
24500 }
24501
24502 case LOOP:
24503 {
24504 if(get_register(sarg2) > 0)
24505 {
24506 ri->pc = sarg1;
24507 increment = false;
24508 }
24509 else
24510 {
24511 set_register(sarg1, sarg1 - 1);
24512 }
24513 }
24514 break;
24515
24516 case RETURN:
24517 {
24518 if (script_funcrun)
24519 break; //handled below, poorly. 'RETURNFUNC' does this better now.
24520 ri->pc = SH::read_stack(ri->sp) - 1;
24521 ++ri->sp;
24522 increment = false;
24523 break;
24524 }
24525
24526 case SETTRUE:
24527 1407410 set_register(sarg1, check_cmp(CMP_EQ) ? 1 : 0);
24528 1407410 break;
24529
24530 case SETFALSE:
24531 1008261 set_register(sarg1, check_cmp(CMP_NE) ? 1 : 0);
24532 1008261 break;
24533
24534 case SETMORE:
24535 1408606 set_register(sarg1, check_cmp(CMP_GE) ? 1 : 0);
24536 1408606 break;
24537
24538 case SETLESS:
24539 112218 set_register(sarg1, check_cmp(CMP_LE) ? 1 : 0);
24540 112218 break;
24541
24542 case SETTRUEI:
24543 set_register(sarg1, check_cmp(CMP_EQ) ? 10000 : 0);
24544 break;
24545
24546 case SETFALSEI:
24547 set_register(sarg1, check_cmp(CMP_NE) ? 10000 : 0);
24548 break;
24549
24550 case SETMOREI:
24551 set_register(sarg1, check_cmp(CMP_GE) ? 10000 : 0);
24552 break;
24553
24554 case SETLESSI:
24555 set_register(sarg1, check_cmp(CMP_LE) ? 10000 : 0);
24556 break;
24557
24558 case READPODARRAYR:
24559 {
24560 212470599 do_readpod(false);
24561 212470599 break;
24562 }
24563 case READPODARRAYV:
24564 {
24565 104059060 do_readpod(true);
24566 104059060 break;
24567 }
24568 case WRITEPODARRAYRR:
24569 {
24570 52004397 do_writepod(false,false);
24571 52004397 break;
24572 }
24573 case WRITEPODARRAYRV:
24574 {
24575 do_writepod(false,true);
24576 break;
24577 }
24578 case WRITEPODARRAYVR:
24579 {
24580 89949202 do_writepod(true,false);
24581 89949202 break;
24582 }
24583 case WRITEPODARRAYVV:
24584 {
24585 2984544 do_writepod(true,true);
24586 2984544 break;
24587 }
24588 case WRITEPODSTRING:
24589 {
24590 3274079 do_writepodstr();
24591 3274079 break;
24592 }
24593 case WRITEPODARRAY:
24594 {
24595 569712 do_writepodarr();
24596 569712 break;
24597 }
24598
24599 case NOT:
24600 do_not(false);
24601 break;
24602
24603 case COMPAREV:
24604 3148656 do_comp(true);
24605 3148656 break;
24606 case COMPAREV2:
24607 do_comp(true,true);
24608 break;
24609
24610 case COMPARER:
24611 7651728 do_comp(false);
24612 7651728 break;
24613
24614 case STRCMPR:
24615 do_internal_strcmp();
24616 break;
24617
24618 case STRICMPR:
24619 do_internal_stricmp();
24620 break;
24621
24622 case SETV:
24623 5663787 do_set_command(true);
24624 5663787 break;
24625
24626 case SETR:
24627 10564123 do_set_command(false);
24628 10564123 break;
24629
24630 case PUSHR:
24631 20510595 do_push(false);
24632 20510595 break;
24633
24634 case PUSHV:
24635 825385 do_push(true);
24636 825385 break;
24637
24638 case PEEK:
24639 do_peek();
24640 break;
24641 case PEEKATV:
24642 do_peekat(true);
24643 break;
24644 case STACKWRITEATRV:
24645 do_writeat(false, true);
24646 break;
24647 case STACKWRITEATVV_IF:
24648 if(!check_cmp(sarg3))
24649 break;
24650 [[fallthrough]];
24651 case STACKWRITEATVV:
24652 do_writeat(true, true);
24653 break;
24654 case POP:
24655 20713642 do_pop();
24656 20713642 break;
24657
24658 case POPARGS:
24659 207868 do_pops();
24660 207868 break;
24661
24662 case PUSHARGSR:
24663 48376 do_pushs(false);
24664 48376 break;
24665
24666 case PUSHARGSV:
24667 do_pushs(true);
24668 break;
24669
24670 case LOADI:
24671 do_loadi();
24672 break;
24673
24674 case STOREI:
24675 do_storei();
24676 break;
24677
24678 case LOADD:
24679 do_loadd();
24680 break;
24681
24682 case LOAD:
24683 20119254 do_load();
24684 20119254 break;
24685
24686 case STORED:
24687 do_stored(false);
24688 break;
24689 case STOREDV:
24690 do_stored(true);
24691 break;
24692 case STORE:
24693 3465034 do_store(false);
24694 3465034 break;
24695 case STOREV:
24696 do_store(true);
24697 break;
24698 case STORE_OBJECT:
24699 do_store_object(false);
24700 break;
24701
24702 // Note: this was never used.
24703 case ALLOCATEGMEMR:
24704 if(type == ScriptType::Global) do_allocatemem(false, false, type, i);
24705
24706 break;
24707
24708 case ALLOCATEGMEMV:
24709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3202 times.
3202 if(type == ScriptType::Global) do_allocatemem(true, false, type, i);
24710
24711 3202 break;
24712
24713 case ALLOCATEMEMR:
24714 do_allocatemem(false, true, type, i);
24715 break;
24716
24717 case ALLOCATEMEMV:
24718 14188523 do_allocatemem(true, true, type, i);
24719 14188523 break;
24720
24721 case RESIZEARRAYR:
24722 1621 do_resize_array();
24723 1621 break;
24724 case OWNARRAYR:
24725 do_own_array(get_register(sarg1), type, i);
24726 break;
24727 case DESTROYARRAYR:
24728 do_destroy_array();
24729 break;
24730
24731 // Pre-3.0, the compiler inserted this command for every local array at the end of it scope.
24732 case DEALLOCATEMEMR:
24733 13664241 do_deallocatemem();
24734 13664241 break;
24735
24736 case SAVEGAMESTRUCTS:
24737 10 using_SRAM = 1;
24738 10 do_savegamestructs(false,false);
24739 10 using_SRAM = 0;
24740 10 break;
24741 case READGAMESTRUCTS:
24742 using_SRAM = 1;
24743 do_loadgamestructs(false,false);
24744 using_SRAM = 0;
24745 break;
24746 case ARRAYSIZE:
24747 303089179 do_arraysize();
24748 303089179 break;
24749
24750 case GETFFCSCRIPT:
24751 10105657 do_getffcscript();
24752 10105657 break;
24753 case GETITEMSCRIPT:
24754 80 do_getitemscript();
24755 80 break;
24756
24757 case LOAD_FFC:
24758 {
24759
1/2
✓ Branch 0 taken 3358372 times.
✗ Branch 1 not taken.
3358372 if (!ZScriptVersion::ffcRefIsSpriteId())
24760 {
24761 set_register(sarg1, get_register(sarg1) - 10000);
24762 break;
24763 }
24764
24765 3358372 int ffc_id = get_register(sarg1) / 10000 - 1;
24766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3358372 times.
3358372 if (auto ffc = ResolveFFCWithID(ffc_id))
24767 3358372 set_register(sarg1, ffc->getUID());
24768 else
24769 set_register(sarg1, 0);
24770 3358372 break;
24771 }
24772
24773 case LOAD_FFC_2:
24774 {
24775 if (!ZScriptVersion::ffcRefIsSpriteId())
24776 {
24777 set_register(sarg1, get_register(sarg2) - 10000);
24778 break;
24779 }
24780
24781 int screen = get_register(sarg1) / 10000;
24782 int index = get_register(sarg2) / 10000;
24783
24784 if (!is_in_current_region(screen))
24785 {
24786 scripting_log_error_with_context("Must use a screen in the current region. got: {}", screen);
24787 break;
24788 }
24789 if (BC::checkMapdataFFC(index) != SH::_NoError)
24790 break;
24791
24792 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + index;
24793 if (auto ffc = ResolveFFCWithID(ffc_id))
24794 set_register(sarg1, ffc->getUID());
24795 else
24796 set_register(sarg1, 0);
24797
24798 break;
24799 }
24800
24801 case CASTBOOLI:
24802 do_boolcast(false);
24803 break;
24804
24805 case CASTBOOLF:
24806 do_boolcast(true);
24807 break;
24808
24809 case ADDV:
24810 2819285 do_add(true);
24811 2819285 break;
24812
24813 case ADDR:
24814 2018844 do_add(false);
24815 2018844 break;
24816
24817 case SUBV:
24818 73824 do_sub(true);
24819 73824 break;
24820 case SUBV2:
24821 6 do_sub(true,true);
24822 6 break;
24823
24824 case SUBR:
24825 141873 do_sub(false);
24826 141873 break;
24827
24828 case MULTV:
24829 3162 do_mult(true);
24830 3162 break;
24831
24832 case MULTR:
24833 269043 do_mult(false);
24834 269043 break;
24835
24836 case DIVV:
24837 do_div(true);
24838 break;
24839 case DIVV2:
24840 do_div(true,true);
24841 break;
24842
24843 case DIVR:
24844 25681 do_div(false);
24845 25681 break;
24846
24847 case MODV:
24848 do_mod(true);
24849 break;
24850 case MODV2:
24851 do_mod(true,true);
24852 break;
24853
24854 case MODR:
24855 42273 do_mod(false);
24856 42273 break;
24857
24858 case SINV:
24859 do_trig(true, 0);
24860 break;
24861
24862 case SINR:
24863 9768934 do_trig(false, 0);
24864 9768934 break;
24865
24866 case COSV:
24867 do_trig(true, 1);
24868 break;
24869
24870 case COSR:
24871 6680540 do_trig(false, 1);
24872 6680540 break;
24873
24874 case TANV:
24875 do_trig(true, 2);
24876 break;
24877
24878 case TANR:
24879 100 do_trig(false, 2);
24880 100 break;
24881
24882 case DEGTORAD:
24883 3916 do_degtorad();
24884 3916 break;
24885
24886 case RADTODEG:
24887 196070 do_radtodeg();
24888 196070 break;
24889
24890 case STRINGLENGTH:
24891 17252 FFCore.do_strlen(false);
24892 17252 break;
24893
24894 case ARCSINR:
24895 14918 do_asin(false);
24896 14918 break;
24897
24898 case ARCCOSR:
24899 do_acos(false);
24900 break;
24901
24902 case ARCTANR:
24903 5902190 do_arctan();
24904 5902190 break;
24905
24906 //Text ptr functions
24907 case FONTHEIGHTR:
24908 32282 do_fontheight();
24909 32282 break;
24910 case STRINGWIDTHR:
24911 18404 do_strwidth();
24912 18404 break;
24913 case CHARWIDTHR:
24914 250385 do_charwidth();
24915 250385 break;
24916 case MESSAGEWIDTHR:
24917 SET_D(rEXP1, 10000* do_msgwidth(get_register(sarg1)/10000));
24918 break;
24919 case MESSAGEHEIGHTR:
24920 SET_D(rEXP1, 10000* do_msgheight(get_register(sarg1)/10000));
24921 break;
24922 //
24923
24924 case COMBO_AT:
24925 {
24926 980737 int32_t x = get_register(sarg1) / 10000;
24927 980737 int32_t y = get_register(sarg2) / 10000;
24928 980737 x = std::clamp(x, 0, world_w - 1);
24929 980737 y = std::clamp(y, 0, world_h - 1);
24930 980737 set_register(sarg1, (int)COMBOPOS_REGION(x, y) * 10000);
24931 980737 break;
24932 }
24933
24934 case COMBO_ADJUST:
24935 {
24936 16 rpos_t rpos = (rpos_t)(get_register(sarg1) / 10000);
24937
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (!is_valid_rpos(rpos))
24938 {
24939 set_register(sarg1, -1);
24940 break;
24941 }
24942
24943 144 auto [x, y] = COMBOXY_REGION(rpos);
24944 32 x += get_register(sarg2) / 10000;
24945 32 y += get_register(sarg3) / 10000;
24946 32 x = std::clamp(x, 0, world_w - 1);
24947 32 y = std::clamp(y, 0, world_h - 1);
24948 48 set_register(sarg1, (int)COMBOPOS_REGION(x, y) * 10000);
24949 16 break;
24950 }
24951
24952 //String.h functions 2.55 Alpha 23
24953 2544 case STRINGCOMPARE: FFCore.do_strcmp(); break;
24954 case STRINGICOMPARE: FFCore.do_stricmp(); break;
24955 14127 case STRINGCOPY: FFCore.do_strcpy(false,false); break;
24956 2 case ARRAYCOPY: FFCore.do_arraycpy(false,false); break;
24957 case STRINGNCOMPARE: FFCore.do_strncmp(); break;
24958 case STRINGNICOMPARE: FFCore.do_strnicmp(); break;
24959
24960 //More string.h functions, 19th May, 2019
24961 case XLEN: FFCore.do_xlen(false); break;
24962 case XTOI: FFCore.do_xtoi(false); break;
24963 case ILEN: FFCore.do_ilen(false); break;
24964 case ATOI: FFCore.do_atoi(false); break;
24965 case ATOL: FFCore.do_atol(false); break;
24966 case STRCSPN: FFCore.do_strcspn(); break;
24967 case STRSTR: FFCore.do_strstr(); break;
24968 14 case XTOA: FFCore.do_xtoa(); break;
24969 4797 case ITOA: FFCore.do_itoa(); break;
24970 56 case ITOACAT: FFCore.do_itoacat(); break;
24971 935 case STRCAT: FFCore.do_strcat(); break;
24972 case STRSPN: FFCore.do_strspn(); break;
24973 case STRCHR: FFCore.do_strchr(); break;
24974 case STRRCHR: FFCore.do_strrchr(); break;
24975 case XLEN2: FFCore.do_xlen2(); break;
24976 case XTOI2: FFCore.do_xtoi2(); break;
24977 case ILEN2: FFCore.do_ilen2(); break;
24978 case ATOI2: FFCore.do_atoi2(); break;
24979 case REMCHR2: FFCore.do_remchr2(); break;
24980 case UPPERTOLOWER: FFCore.do_UpperToLower(false); break;
24981 2 case LOWERTOUPPER: FFCore.do_LowerToUpper(false); break;
24982 case CONVERTCASE: FFCore.do_ConvertCase(false); break;
24983
24984 case GETNPCSCRIPT: FFCore.do_getnpcscript(); break;
24985 234 case GETCOMBOSCRIPT: FFCore.do_getcomboscript(); break;
24986 7914 case GETLWEAPONSCRIPT: FFCore.do_getlweaponscript(); break;
24987 4636 case GETEWEAPONSCRIPT: FFCore.do_geteweaponscript(); break;
24988 case GETHEROSCRIPT: FFCore.do_getheroscript(); break;
24989 137138 case GETGENERICSCRIPT: FFCore.do_getgenericscript(); break;
24990 case GETGLOBALSCRIPT: FFCore.do_getglobalscript(); break;
24991 906 case GETDMAPSCRIPT: FFCore.do_getdmapscript(); break;
24992 case GETSCREENSCRIPT: FFCore.do_getscreenscript(); break;
24993 115 case GETSPRITESCRIPT: FFCore.do_getitemspritescript(); break;
24994 case GETUNTYPEDSCRIPT: FFCore.do_getuntypedscript(); break;
24995 case GETSUBSCREENSCRIPT:FFCore.do_getsubscreenscript(); break;
24996 case GETNPCBYNAME: FFCore.do_getnpcbyname(); break;
24997 case GETITEMBYNAME: FFCore.do_getitembyname(); break;
24998 case GETCOMBOBYNAME: FFCore.do_getcombobyname(); break;
24999 case GETDMAPBYNAME: FFCore.do_getdmapbyname(); break;
25000
25001 case ABS:
25002 9100 do_abs(false);
25003 9100 break;
25004
25005 case MINR:
25006 2170 do_min(false);
25007 2170 break;
25008
25009 case MINV:
25010 do_min(true);
25011 break;
25012
25013 case MAXR:
25014 1332 do_max(false);
25015 1332 break;
25016 case MAXV:
25017 do_max(true);
25018 break;
25019 case WRAPRADIANS:
25020 8306 do_wrap_rad(false);
25021 8306 break;
25022 case WRAPDEGREES:
25023 13037 do_wrap_deg(false);
25024 13037 break;
25025
25026 case MAXVARG:
25027 1570475 FFCore.do_varg_max();
25028 1570475 break;
25029 case MINVARG:
25030 162607 FFCore.do_varg_min();
25031 162607 break;
25032 case CHOOSEVARG:
25033 602347 FFCore.do_varg_choose();
25034 602347 break;
25035 case MAKEVARGARRAY:
25036
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 assert(sarg1 >= 0 && sarg1 <= (int)script_object_type::last);
25037 30 FFCore.do_varg_makearray(type, i, (script_object_type)sarg1);
25038 30 break;
25039
25040 case PUSHVARGV:
25041 3523313 do_push_varg(true);
25042 3523313 break;
25043 case PUSHVARGR:
25044 1820491 do_push_varg(false);
25045 1820491 break;
25046 case PUSHVARGSV:
25047 2674 do_push_vargs(true);
25048 2674 break;
25049 case PUSHVARGSR:
25050 do_push_vargs(false);
25051 break;
25052
25053 case RNDR:
25054 2918055 do_rnd(false);
25055 2918055 break;
25056
25057 case RNDV:
25058 do_rnd(true);
25059 break;
25060
25061 case SRNDR:
25062 do_srnd(false);
25063 break;
25064
25065 case SRNDV:
25066 do_srnd(true);
25067 break;
25068
25069 case SRNDRND:
25070 do_srndrnd();
25071 break;
25072
25073 case GETRTCTIMER:
25074 15 FFCore.getRTC();
25075 15 break;
25076
25077 case FACTORIAL:
25078 do_factorial(false);
25079 break;
25080
25081 case SQROOTV:
25082 do_sqroot(true);
25083 break;
25084
25085 case SQROOTR:
25086 10089782 do_sqroot(false);
25087 10089782 break;
25088
25089 case POWERR:
25090 6556 do_power(false);
25091 6556 break;
25092 case POWERV:
25093 do_power(true);
25094 break;
25095 case POWERV2:
25096 do_power(true,true);
25097 break;
25098
25099 case LPOWERR:
25100 do_lpower(false);
25101 break;
25102 case LPOWERV:
25103 do_lpower(true);
25104 break;
25105 case LPOWERV2:
25106 do_lpower(true,true);
25107 break;
25108
25109 case IPOWERR:
25110 do_ipower(false);
25111 break;
25112
25113 case IPOWERV:
25114 do_ipower(true);
25115 break;
25116
25117 case LOG10:
25118 969 do_log10(false);
25119 969 break;
25120
25121 case LOGE:
25122 648 do_naturallog(false);
25123 648 break;
25124
25125 case ANDR:
25126 165132 do_and(false);
25127 165132 break;
25128
25129 case ANDV:
25130 do_and(true);
25131 break;
25132
25133 case ORR:
25134 4411 do_or(false);
25135 4411 break;
25136
25137 case ORV:
25138 do_or(true);
25139 break;
25140
25141 case XORR:
25142 678025 do_xor(false);
25143 678025 break;
25144
25145 case XORV:
25146 249892 do_xor(true);
25147 249892 break;
25148
25149 case NANDR:
25150 do_nand(false);
25151 break;
25152
25153 case NANDV:
25154 do_nand(true);
25155 break;
25156
25157 case NORR:
25158 do_nor(false);
25159 break;
25160
25161 case NORV:
25162 do_nor(true);
25163 break;
25164
25165 case XNORR:
25166 do_xnor(false);
25167 break;
25168
25169 case XNORV:
25170 do_xnor(true);
25171 break;
25172
25173 case BITNOT:
25174 3719887 do_bitwisenot(false);
25175 3719887 break;
25176
25177 case LSHIFTR:
25178 80068802 do_lshift(false);
25179 80068802 break;
25180
25181 case LSHIFTV:
25182 4965499 do_lshift(true);
25183 4965499 break;
25184
25185 case RSHIFTR:
25186 27016621 do_rshift(false);
25187 27016621 break;
25188
25189 case RSHIFTV:
25190 4974468 do_rshift(true);
25191 4974468 break;
25192
25193 case ANDR32:
25194 352043 do_and32(false);
25195 352043 break;
25196
25197 case ANDV32:
25198 10744 do_and32(true);
25199 10744 break;
25200
25201 case ORR32:
25202 do_or32(false);
25203 break;
25204
25205 case ORV32:
25206 do_or32(true);
25207 break;
25208
25209 case XORR32:
25210 do_xor32(false);
25211 break;
25212
25213 case XORV32:
25214 do_xor32(true);
25215 break;
25216
25217 case BITNOT32:
25218 4 do_bitwisenot32(false);
25219 4 break;
25220
25221 case LSHIFTR32:
25222 317888 do_lshift32(false);
25223 317888 break;
25224
25225 case LSHIFTV32:
25226 do_lshift32(true);
25227 break;
25228
25229 case RSHIFTR32:
25230 34296 do_rshift32(false);
25231 34296 break;
25232
25233 case RSHIFTV32:
25234 do_rshift32(true);
25235 break;
25236
25237 case TRACER:
25238 12533 FFCore.do_trace(false);
25239 12533 break;
25240
25241 case TRACELR:
25242 FFCore.do_tracel(false);
25243 break;
25244
25245 case TRACEV:
25246 34 FFCore.do_trace(true);
25247 34 break;
25248
25249 case TRACE2R:
25250 FFCore.do_tracebool(false);
25251 break;
25252
25253 //Zap and Wavy Effects
25254 case FXWAVYR:
25255 FFCore.do_fx_wavy(false);
25256 break;
25257 case FXZAPR:
25258 FFCore.do_fx_zap(false);
25259 break;
25260 //Zap and Wavy Effects
25261 case FXWAVYV:
25262 FFCore.do_fx_wavy(true);
25263 break;
25264 case FXZAPV:
25265 FFCore.do_fx_zap(true);
25266 break;
25267 case GREYSCALER:
25268 FFCore.do_greyscale(false);
25269 break;
25270 case GREYSCALEV:
25271 FFCore.do_greyscale(true);
25272 break;
25273 case MONOCHROMER:
25274 FFCore.do_monochromatic(false);
25275 break;
25276 case MONOCHROMEV:
25277 FFCore.do_monochromatic(true);
25278 break;
25279
25280 case TRACE2V:
25281 FFCore.do_tracebool(true);
25282 break;
25283
25284 case TRACE3:
25285 22 FFCore.do_tracenl();
25286 22 break;
25287
25288 case TRACE4:
25289 2 FFCore.do_cleartrace();
25290 2 break;
25291
25292 case TRACE5:
25293 3 FFCore.do_tracetobase();
25294 3 break;
25295
25296 case TRACE6:
25297 1383 FFCore.do_tracestring();
25298 1383 break;
25299
25300 case PRINTFV:
25301 287 FFCore.do_printf(true, false);
25302 287 break;
25303 case SPRINTFV:
25304 11645 do_sprintf(true, false);
25305 11645 break;
25306
25307 case PRINTFVARG:
25308 33594 FFCore.do_printf(true, true);
25309 33594 break;
25310 case SPRINTFVARG:
25311 12284 do_sprintf(true, true);
25312 12284 break;
25313 case PRINTFA:
25314 FFCore.do_printfarr();
25315 break;
25316 case SPRINTFA:
25317 do_sprintfarr();
25318 break;
25319 case ARRAYPUSH:
25320 {
25321 15 auto ptr = SH::read_stack(ri->sp + 2);
25322 15 auto val = SH::read_stack(ri->sp + 1);
25323 15 auto indx = SH::read_stack(ri->sp + 0) / 10000;
25324 15 ArrayManager am(ptr);
25325 15 SET_D(rEXP1, am.push(val,indx) ? 10000 : 0);
25326 15 break;
25327 }
25328 case ARRAYPOP:
25329 {
25330 3 auto ptr = SH::read_stack(ri->sp + 1);
25331 3 auto indx = SH::read_stack(ri->sp + 0) / 10000;
25332 3 ArrayManager am(ptr);
25333 3 SET_D(rEXP1, am.pop(indx));
25334 3 break;
25335 }
25336
25337 case BREAKPOINT:
25338 FFCore.do_breakpoint();
25339 break;
25340
25341 case WARP:
25342 do_warp(true);
25343 break;
25344
25345 case WARPR:
25346 123 do_warp(false);
25347 123 break;
25348
25349 case PITWARP:
25350 do_pitwarp(true);
25351 break;
25352
25353 case PITWARPR:
25354 127 do_pitwarp(false);
25355 127 break;
25356
25357 case SELECTAWPNV:
25358 do_selectweapon(true, 1);
25359 break;
25360
25361 case SELECTAWPNR:
25362 5660 do_selectweapon(false, 1);
25363 5660 break;
25364
25365 case SELECTBWPNV:
25366 do_selectweapon(true, 0);
25367 break;
25368
25369 case SELECTBWPNR:
25370 5436 do_selectweapon(false, 0);
25371 5436 break;
25372
25373 case SELECTXWPNR:
25374 do_selectweapon(false, 2);
25375 break;
25376
25377 case SELECTYWPNR:
25378 do_selectweapon(false, 3);
25379 break;
25380
25381 case PLAYSOUNDR:
25382 427914 do_sfx(false);
25383 427914 break;
25384
25385 case PLAYSOUNDV:
25386 do_sfx(true);
25387 break;
25388
25389 case ADJUSTSFXVOLUMER: FFCore.do_adjustsfxvolume(false); break;
25390 case ADJUSTSFXVOLUMEV: FFCore.do_adjustsfxvolume(true); break;
25391 2004 case ADJUSTVOLUMER: FFCore.do_adjustvolume(false); break;
25392 case ADJUSTVOLUMEV: FFCore.do_adjustvolume(true); break;
25393
25394 case PLAYMIDIR:
25395 63830 do_midi(false);
25396 63830 break;
25397
25398 case PLAYMIDIV:
25399 do_midi(true);
25400 break;
25401
25402 case PLAYENHMUSIC:
25403 357 do_enh_music(false);
25404 357 break;
25405
25406 case GETMUSICFILE:
25407 236 do_get_enh_music_filename(false);
25408 236 break;
25409
25410 case GETMUSICTRACK:
25411 140 do_get_enh_music_track(false);
25412 140 break;
25413
25414 case SETDMAPENHMUSIC:
25415 3807 do_set_dmap_enh_music(false);
25416 3807 break;
25417
25418 // Audio->
25419
25420 case ENDSOUNDR:
25421 1 stop_sfx(false);
25422 1 break;
25423
25424 case ENDSOUNDV:
25425 stop_sfx(true);
25426 break;
25427
25428 case PAUSESOUNDR:
25429 pause_sfx(false);
25430 break;
25431
25432 case PAUSESOUNDV:
25433 pause_sfx(true);
25434 break;
25435
25436 case RESUMESOUNDR:
25437 resume_sfx(false);
25438 break;
25439
25440 case RESUMESOUNDV:
25441 resume_sfx(true);
25442 break;
25443
25444
25445
25446 case PAUSESFX:
25447 {
25448 int32_t sound = GET_D(rINDEX)/10000;
25449 pause_sfx(sound);
25450
25451 }
25452 break;
25453
25454 case RESUMESFX:
25455 {
25456 int32_t sound = GET_D(rINDEX)/10000;
25457 resume_sfx(sound);
25458 }
25459 break;
25460
25461 case ADJUSTSFX:
25462 {
25463 do_sfx_ex(false);
25464 }
25465 break;
25466
25467 case PLAYSOUNDEX:
25468 {
25469 14 do_sfx_ex(true);
25470 }
25471 14 break;
25472
25473 case GETSFXCOMPLETION:
25474 {
25475 do_get_sfx_completion();
25476 }
25477 break;
25478
25479 case CONTINUESFX:
25480 {
25481 int32_t sound = GET_D(rINDEX)/10000;
25482 //Backend::sfx->cont_sfx(sound);
25483
25484 //! cont_sfx was not ported to the new back end!!!
25485 // I believe this restarted the loop.
25486 resume_sfx(sound);
25487 //What was the old instruction, again? Did it exist? -Z
25488 //continue_sfx(sound);
25489 }
25490 break;
25491
25492
25493 /*
25494 case STOPITEMSOUND:
25495 void stop_item_sfx(int32_t family)
25496 */
25497
25498 // Note: these have never worked.
25499 case PAUSEMUSIC:
25500 //What was the instruction prior to adding backends?
25501 //! The pauseAll() function pauses sfx, not music, so this instruction is not doing what I intended. -Z
25502 //Check AllOff() -Z
25503 //zcmusic_pause(ZCMUSIC* zcm, int32_t pause); is in zcmusic.h
25504 // midi_paused = true;
25505 //pause_all_sfx();
25506
25507 //Backend::sfx->pauseAll();
25508 break;
25509 case RESUMEMUSIC:
25510 //What was the instruction prior to adding backends?
25511 //Check AllOff() -Z
25512 //resume_all_sfx();
25513 // midi_paused = false;
25514 //Backend::sfx->resumeAll();
25515 break;
25516
25517 case MSGSTRR:
25518 1351 do_message(false);
25519 1351 break;
25520
25521 case MSGSTRV:
25522 do_message(true);
25523 break;
25524
25525 case ITEMNAME:
25526 2768 do_getitemname();
25527 2768 break;
25528
25529 case LOADLWEAPONR:
25530 1860392 do_loadlweapon(false);
25531 1860392 break;
25532
25533 case LOADLWEAPONV:
25534 do_loadlweapon(true);
25535 break;
25536
25537 case LOADEWEAPONR:
25538 5661515 do_loadeweapon(false);
25539 5661515 break;
25540
25541 case LOADEWEAPONV:
25542 do_loadeweapon(true);
25543 break;
25544
25545 case LOADITEMR:
25546 585769 do_loaditem(false);
25547 585769 break;
25548
25549 case LOADITEMV:
25550 do_loaditem(true);
25551 break;
25552
25553 case LOADITEMDATAR:
25554 58103417 do_loaditemdata(false);
25555 58103417 break;
25556
25557 //New Datatypes
25558 case LOADSHOPR:
25559 FFScript::do_loadshopdata(false);
25560 break;
25561 case LOADSHOPV:
25562 FFScript::do_loadshopdata(true);
25563 break;
25564
25565 case LOADINFOSHOPR:
25566 FFScript::do_loadinfoshopdata(false);
25567 break;
25568 case LOADINFOSHOPV:
25569 FFScript::do_loadinfoshopdata(true);
25570 break;
25571 case LOADNPCDATAR:
25572 6366 FFScript::do_loadnpcdata(false);
25573 6366 break;
25574 case LOADNPCDATAV:
25575 FFScript::do_loadnpcdata(true);
25576 break;
25577
25578 case LOADCOMBODATAR:
25579 6042586 FFScript::do_loadcombodata(false);
25580 6042586 break;
25581 case LOADCOMBODATAV:
25582 FFScript::do_loadcombodata(true);
25583 break;
25584
25585 case LOADTMPSCR:
25586 3585254 FFScript::do_loadmapdata_tempscr(false);
25587 3585254 break;
25588 case LOADTMPSCR2:
25589 FFScript::do_loadmapdata_tempscr2(false);
25590 break;
25591 case REGION_LOAD_TMPSCR_FOR_LAYER_COMBO_POS:
25592 do_loadtmpscrforcombopos(false);
25593 break;
25594 case LOADSCROLLSCR:
25595 182518 FFScript::do_loadmapdata_scrollscr(false);
25596 182518 break;
25597 case LOADSCROLLSCR2:
25598 FFScript::do_loadmapdata_scrollscr2(false);
25599 break;
25600
25601 case LOADSPRITEDATAR:
25602 5603 FFScript::do_loadspritedata(false);
25603 5603 break;
25604 case LOADSPRITEDATAV:
25605 FFScript::do_loadspritedata(true);
25606 break;
25607
25608 case LOADBITMAPDATAR:
25609 10 FFScript::do_loadbitmapid(false);
25610 10 break;
25611
25612
25613 case LOADBITMAPDATAV:
25614 FFScript::do_loadbitmapid(true);
25615 break;
25616
25617 //functions
25618 case CREATEPALDATA:
25619 223 FFCore.do_create_paldata(); break;
25620 case CREATEPALDATACLR:
25621 11 FFCore.do_create_paldata_clr(); break;
25622 case MIXCLR:
25623 FFCore.do_mix_clr(); break;
25624 case CREATERGBHEX:
25625 FFCore.do_create_rgb_hex(); break;
25626 case CREATERGB:
25627 11 FFCore.do_create_rgb(); break;
25628 case CONVERTFROMRGB:
25629 FFCore.do_convert_from_rgb(); break;
25630 case CONVERTTORGB:
25631 FFCore.do_convert_to_rgb(); break;
25632 case PALDATALOADLEVEL:
25633 24 FFCore.do_paldata_load_level(); break;
25634 case PALDATALOADSPRITE:
25635 87 FFCore.do_paldata_load_sprite(); break;
25636 case PALDATALOADMAIN:
25637 92 FFCore.do_paldata_load_main(); break;
25638 case PALDATALOADCYCLE:
25639 FFCore.do_paldata_load_cycle(); break;
25640 case PALDATALOADBITMAP:
25641 FFCore.do_paldata_load_bitmap(); break;
25642 case PALDATAWRITELEVEL:
25643 370 FFCore.do_paldata_write_level(); break;
25644 case PALDATAWRITELEVELCS:
25645 FFCore.do_paldata_write_levelcset(); break;
25646 case PALDATAWRITESPRITE:
25647 31 FFCore.do_paldata_write_sprite(); break;
25648 case PALDATAWRITESPRITECS:
25649 FFCore.do_paldata_write_spritecset(); break;
25650 case PALDATAWRITEMAIN:
25651 1064 FFCore.do_paldata_write_main(); break;
25652 case PALDATAWRITEMAINCS:
25653 130 FFCore.do_paldata_write_maincset(); break;
25654 case PALDATAWRITECYCLE:
25655 FFCore.do_paldata_write_cycle(); break;
25656 case PALDATAWRITECYCLECS:
25657 FFCore.do_paldata_write_cyclecset(); break;
25658 case PALDATAVALIDCLR:
25659 FFCore.do_paldata_colorvalid(); break;
25660 case PALDATACLEARCLR:
25661 FFCore.do_paldata_clearcolor(); break;
25662 case PALDATACLEARCSET:
25663 FFCore.do_paldata_clearcset(); break;
25664 case PALDATAMIX:
25665 450 FFCore.do_paldata_mix(); break;
25666 case PALDATAMIXCS:
25667 4781 FFCore.do_paldata_mixcset(); break;
25668 case PALDATACOPY:
25669 FFCore.do_paldata_copy(); break;
25670 case PALDATACOPYCSET:
25671 112 FFCore.do_paldata_copycset(); break;
25672 case PALDATAFREE:
25673
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 234 times.
234 if (user_paldata* pd = checkPalData(GET_REF(paldataref), true))
25674 {
25675 234 free_script_object(pd->id);
25676 234 }
25677 234 break;
25678 case PALDATAOWN:
25679 if (user_paldata* pd = checkPalData(GET_REF(paldataref), false))
25680 {
25681 own_script_object(pd, type, i);
25682 }
25683 break;
25684 case LOADRNG: //command
25685 932 FFCore.do_loadrng(); break;
25686
25687 case ITEMGETDISPLAYNAME: //command
25688 53 item_display_name(false); break;
25689 case ITEMSETDISPLAYNAME: //command
25690 item_display_name(true); break;
25691 case ITEMGETSHOWNNAME: //command
25692 item_shown_name(); break;
25693
25694 case DMAPDATAGETNAMER: //command
25695 FFScript::do_getDMapData_dmapname(false); break;
25696 case DMAPDATAGETNAMEV: //command
25697 FFScript::do_getDMapData_dmapname(true); break;
25698
25699 case DMAPDATASETNAMER: //command
25700 FFScript::do_setDMapData_dmapname(false); break;
25701 case DMAPDATASETNAMEV: //command
25702 FFScript::do_setDMapData_dmapname(true); break;
25703
25704
25705
25706 case DMAPDATAGETTITLER: //command
25707 FFScript::do_getDMapData_dmaptitle(false); break;
25708 case DMAPDATAGETTITLEV: //command
25709 FFScript::do_getDMapData_dmaptitle(true); break;
25710 case DMAPDATASETTITLER: //command
25711 FFScript::do_setDMapData_dmaptitle(false); break;
25712 case DMAPDATASETTITLEV: //command
25713 FFScript::do_setDMapData_dmaptitle(true); break;
25714
25715
25716 case DMAPDATAGETINTROR: //command
25717 FFScript::do_getDMapData_dmapintro(false); break;
25718 case DMAPDATAGETINTROV: //command
25719 FFScript::do_getDMapData_dmapintro(true); break;
25720 case DMAPDATANSETITROR: //command
25721 FFScript::do_setDMapData_dmapintro(false); break;
25722 case DMAPDATASETINTROV: //command
25723 FFScript::do_setDMapData_dmapintro(true); break;
25724
25725
25726 case DMAPDATAGETMUSICR: //command, string to load a music file
25727 14 FFScript::do_getDMapData_music(false); break;
25728 case DMAPDATAGETMUSICV: //command, string to load a music file
25729 FFScript::do_getDMapData_music(true); break;
25730 case DMAPDATASETMUSICR: //command, string to load a music file
25731 FFScript::do_setDMapData_music(false); break;
25732 case DMAPDATASETMUSICV: //command, string to load a music file
25733 FFScript::do_setDMapData_music(true); break;
25734
25735 case LOADMESSAGEDATAR: //COMMAND
25736 54 FFScript::do_loadmessagedata(false);
25737 54 break;
25738 case LOADMESSAGEDATAV: //COMMAND
25739 FFScript::do_loadmessagedata(false);
25740 break;
25741
25742
25743 case MESSAGEDATASETSTRINGR: //command
25744 52 FFScript::do_messagedata_setstring(false);
25745 52 break;
25746 case MESSAGEDATASETSTRINGV: //command
25747 FFScript::do_messagedata_setstring(false);
25748 break;
25749
25750 case MESSAGEDATAGETSTRINGR: //command
25751 18 FFScript::do_messagedata_getstring(false);
25752 18 break;
25753 case MESSAGEDATAGETSTRINGV: //command
25754 FFScript::do_messagedata_getstring(false);
25755 break;
25756 case LOADITEMDATAV:
25757 do_loaditemdata(true);
25758 break;
25759
25760 case LOADNPCBYSUID:
25761 12 FFCore.do_loadnpc_by_script_uid(false);
25762 12 break;
25763
25764 case LOADLWEAPONBYSUID:
25765 598 FFCore.do_loadlweapon_by_script_uid(false);
25766 598 break;
25767
25768 case LOADWEAPONCBYSUID:
25769 FFCore.do_loadeweapon_by_script_uid(false);
25770 break;
25771
25772 case LOADNPCR:
25773 32179028 do_loadnpc(false);
25774 32179028 break;
25775
25776 case LOADNPCV:
25777 do_loadnpc(true);
25778 break;
25779
25780 case CREATELWEAPONR:
25781 166704 do_createlweapon(false);
25782 166704 break;
25783
25784 case CREATELWEAPONV:
25785 do_createlweapon(true);
25786 break;
25787
25788 case CREATEEWEAPONR:
25789 303017 do_createeweapon(false);
25790 303017 break;
25791
25792 case CREATEEWEAPONV:
25793 do_createeweapon(true);
25794 break;
25795
25796 case CREATEITEMR:
25797 22558 do_createitem(false);
25798 22558 break;
25799
25800 case CREATEITEMV:
25801 do_createitem(true);
25802 break;
25803
25804 case CREATENPCR:
25805 3593 do_createnpc(false);
25806 3593 break;
25807
25808 case CREATENPCV:
25809 do_createnpc(true);
25810 break;
25811
25812 case ISVALIDARRAY:
25813 601509 do_isvalidarray();
25814 601509 break;
25815
25816 case ISVALIDITEM:
25817 31517 do_isvaliditem();
25818 31517 break;
25819
25820 case ISVALIDBITMAP:
25821 8420 FFCore.do_isvalidbitmap();
25822 8420 break;
25823
25824 case ISALLOCATEDBITMAP:
25825 117 FFCore.do_isallocatedbitmap();
25826 117 break;
25827
25828 case ISVALIDNPC:
25829 11796078 do_isvalidnpc();
25830 11796078 break;
25831
25832 case ISVALIDLWPN:
25833 1279180 do_isvalidlwpn();
25834 1279180 break;
25835
25836 case ISVALIDEWPN:
25837 176099 do_isvalidewpn();
25838 176099 break;
25839
25840 case LWPNMAKEANGULAR:
25841 do_lwpnmakeangular();
25842 break;
25843
25844 case EWPNMAKEANGULAR:
25845 do_ewpnmakeangular();
25846 break;
25847
25848 case LWPNMAKEDIRECTIONAL:
25849 do_lwpnmakedirectional();
25850 break;
25851
25852 case EWPNMAKEDIRECTIONAL:
25853 do_ewpnmakedirectional();
25854 break;
25855
25856 case LWPNUSESPRITER:
25857 20064 do_lwpnusesprite(false);
25858 20064 break;
25859
25860 case LWPNUSESPRITEV:
25861 do_lwpnusesprite(true);
25862 break;
25863
25864 case EWPNUSESPRITER:
25865 296065 do_ewpnusesprite(false);
25866 296065 break;
25867
25868 case EWPNUSESPRITEV:
25869 do_ewpnusesprite(true);
25870 break;
25871
25872 case CLEARSPRITESR:
25873 do_clearsprites(false);
25874 break;
25875
25876 case CLEARSPRITESV:
25877 do_clearsprites(true);
25878 break;
25879
25880 case ISSOLID:
25881 25461489 do_issolid();
25882 25461489 break;
25883
25884 case MAPDATAISSOLID:
25885 do_mapdataissolid();
25886 break;
25887
25888 case MAPDATAISSOLIDLYR:
25889 do_mapdataissolid_layer();
25890 break;
25891
25892 case ISSOLIDLAYER:
25893 do_issolid_layer();
25894 break;
25895
25896 case SETSIDEWARP:
25897 257 do_setsidewarp();
25898 257 break;
25899
25900 case SETTILEWARP:
25901 5 do_settilewarp();
25902 5 break;
25903
25904 case GETSIDEWARPDMAP:
25905 364895 do_getsidewarpdmap(false);
25906 364895 break;
25907
25908 case GETSIDEWARPSCR:
25909 3 do_getsidewarpscr(false);
25910 3 break;
25911
25912 case GETSIDEWARPTYPE:
25913 do_getsidewarptype(false);
25914 break;
25915
25916 case GETTILEWARPDMAP:
25917 364942 do_gettilewarpdmap(false);
25918 364942 break;
25919
25920 case GETTILEWARPSCR:
25921 50 do_gettilewarpscr(false);
25922 50 break;
25923
25924 case GETTILEWARPTYPE:
25925 3 do_gettilewarptype(false);
25926 3 break;
25927
25928 case LAYERSCREEN:
25929 13670631 do_layerscreen();
25930 13670631 break;
25931
25932 case LAYERMAP:
25933 18282859 do_layermap();
25934 18282859 break;
25935
25936 case SECRETS:
25937 382 do_triggersecrets(GET_REF(screenref));
25938 382 break;
25939
25940 case REGION_TRIGGER_SECRETS:
25941 {
25942 118 int screen = get_register(sarg1) / 10000;
25943
1/2
✓ Branch 0 taken 118 times.
✗ Branch 1 not taken.
118 if (!is_in_current_region(screen))
25944 {
25945 scripting_log_error_with_context("Must use a screen in the current region. got: {}", screen);
25946 break;
25947 }
25948
25949 118 do_triggersecrets(screen);
25950 118 break;
25951 }
25952
25953 case GRAPHICSGETPIXEL:
25954 FFCore.do_graphics_getpixel();
25955 break;
25956 case GRAPHICSCOUNTCOLOR:
25957 FFCore.do_bmpcollision();
25958 break;
25959
25960 case COMBOTILE:
25961 3182 do_combotile(false);
25962 3182 break;
25963
25964 case DRAWLIGHT_CIRCLE:
25965 {
25966 if (get_qr(qr_SCRIPTS_SCREEN_DRAW_LIGHT_NO_OFFSET))
25967 {
25968 static const int ARGS = 7;
25969 zfix cx = zslongToFix(SH::read_stack(ri->sp + (ARGS-1)));
25970 zfix cy = zslongToFix(SH::read_stack(ri->sp + (ARGS-2)));
25971 int radius = SH::read_stack(ri->sp + (ARGS-3));
25972 int transp_rad = SH::read_stack(ri->sp + (ARGS-4));
25973 int dith_rad = SH::read_stack(ri->sp + (ARGS-5));
25974 int dith_type = SH::read_stack(ri->sp + (ARGS-6));
25975 int dith_arg = SH::read_stack(ri->sp + (ARGS-7));
25976 if(radius >= 0) radius /= 10000;
25977 else radius = game->get_light_rad();
25978 if(!radius) break;
25979 if(transp_rad >= 0) transp_rad /= 10000;
25980 if(dith_rad >= 0) dith_rad /= 10000;
25981 if(dith_type >= 0) dith_type /= 10000;
25982 if(dith_arg >= 0) dith_arg /= 10000;
25983
25984 doDarkroomCircle(cx,cy,radius,darkscr_bmp,nullptr,dith_rad,transp_rad,dith_type,dith_arg);
25985 }
25986 else do_drawing_command(scommand, true);
25987
25988 break;
25989 }
25990 case DRAWLIGHT_SQUARE:
25991 {
25992 if (get_qr(qr_SCRIPTS_SCREEN_DRAW_LIGHT_NO_OFFSET))
25993 {
25994 static const int ARGS = 7;
25995 zfix cx = zslongToFix(SH::read_stack(ri->sp + (ARGS-1)));
25996 zfix cy = zslongToFix(SH::read_stack(ri->sp + (ARGS-2)));
25997 int radius = SH::read_stack(ri->sp + (ARGS-3));
25998 int transp_rad = SH::read_stack(ri->sp + (ARGS-4));
25999 int dith_rad = SH::read_stack(ri->sp + (ARGS-5));
26000 int dith_type = SH::read_stack(ri->sp + (ARGS-6));
26001 int dith_arg = SH::read_stack(ri->sp + (ARGS-7));
26002 if(radius >= 0) radius /= 10000;
26003 else radius = game->get_light_rad();
26004 if(!radius) break;
26005 if(transp_rad >= 0) transp_rad /= 10000;
26006 if(dith_rad >= 0) dith_rad /= 10000;
26007 if(dith_type >= 0) dith_type /= 10000;
26008 if(dith_arg >= 0) dith_arg /= 10000;
26009
26010 doDarkroomSquare(cx,cy,radius,darkscr_bmp,nullptr,dith_rad,transp_rad,dith_type,dith_arg);
26011 }
26012 else do_drawing_command(scommand, true);
26013
26014 break;
26015 }
26016 case DRAWLIGHT_CONE:
26017 {
26018 if (get_qr(qr_SCRIPTS_SCREEN_DRAW_LIGHT_NO_OFFSET))
26019 {
26020 static const int ARGS = 8;
26021 zfix cx = zslongToFix(SH::read_stack(ri->sp + (ARGS-1)));
26022 zfix cy = zslongToFix(SH::read_stack(ri->sp + (ARGS-2)));
26023 int dir = SH::read_stack(ri->sp + (ARGS-3)) / 10000;
26024 int length = SH::read_stack(ri->sp + (ARGS-4));
26025 int transp_rad = SH::read_stack(ri->sp + (ARGS-5));
26026 int dith_rad = SH::read_stack(ri->sp + (ARGS-6));
26027 int dith_type = SH::read_stack(ri->sp + (ARGS-7));
26028 int dith_arg = SH::read_stack(ri->sp + (ARGS-8));
26029 if(length >= 0) length /= 10000;
26030 else length = game->get_light_rad()*2;
26031 if(!length) break;
26032 if(dir < 0) break;
26033 else dir = NORMAL_DIR(dir);
26034 if(transp_rad >= 0) transp_rad /= 10000;
26035 if(dith_rad >= 0) dith_rad /= 10000;
26036 if(dith_type >= 0) dith_type /= 10000;
26037 if(dith_arg >= 0) dith_arg /= 10000;
26038
26039 doDarkroomCone(cx,cy,length,dir,darkscr_bmp,nullptr,dith_rad,transp_rad,dith_type,dith_arg);
26040 }
26041 else do_drawing_command(scommand, true);
26042
26043 break;
26044 }
26045
26046 case RECTR:
26047 case CIRCLER:
26048 case ARCR:
26049 case ELLIPSER:
26050 case LINER:
26051 case PUTPIXELR:
26052 case PIXELARRAYR:
26053 case TILEARRAYR:
26054 case LINESARRAY:
26055 case COMBOARRAYR:
26056 case DRAWTILER:
26057 case DRAWTILECLOAKEDR:
26058 case DRAWCOMBOR:
26059 case DRAWCOMBOCLOAKEDR:
26060 case DRAWCHARR:
26061 case DRAWINTR:
26062 case QUADR:
26063 case TRIANGLER:
26064 case QUAD3DR:
26065 case TRIANGLE3DR:
26066 case FASTTILER:
26067 case FASTCOMBOR:
26068 case DRAWSTRINGR:
26069 case DRAWSTRINGR2:
26070 case BMPDRAWSTRINGR2:
26071 case SPLINER:
26072 case BITMAPR:
26073 case BITMAPEXR:
26074 case DRAWLAYERR:
26075 case DRAWSCREENR:
26076 case POLYGONR:
26077 case FRAMER:
26078 case TILEBLIT:
26079 case COMBOBLIT:
26080 53527326 do_drawing_command(scommand, true);
26081 53527326 break;
26082
26083 case BMPRECTR:
26084 case BMPCIRCLER:
26085 case BMPARCR:
26086 case BMPELLIPSER:
26087 case BMPLINER:
26088 case BMPSPLINER:
26089 case BMPPUTPIXELR:
26090 case BMPDRAWTILER:
26091 case BMPDRAWTILECLOAKEDR:
26092 case BMPDRAWCOMBOR:
26093 case BMPDRAWCOMBOCLOAKEDR:
26094 case BMPFASTTILER:
26095 case BMPFASTCOMBOR:
26096 case BMPDRAWCHARR:
26097 case BMPDRAWINTR:
26098 case BMPDRAWSTRINGR:
26099 case BMPQUADR:
26100 case BMPQUAD3DR:
26101 case BMPTRIANGLER:
26102 case BMPTRIANGLE3DR:
26103 case BMPPOLYGONR:
26104 case BMPDRAWLAYERR:
26105 case BMPDRAWLAYERSOLIDR:
26106 case BMPDRAWLAYERCFLAGR:
26107 case BMPDRAWLAYERCTYPER:
26108 case BMPDRAWLAYERCIFLAGR:
26109 case BMPDRAWLAYERSOLIDITYR:
26110 case BMPDRAWSCREENR:
26111 case BMPDRAWSCREENSOLIDR:
26112 case BMPDRAWSCREENSOLID2R:
26113 case BMPDRAWSCREENCOMBOFR:
26114 case BMPDRAWSCREENCOMBOIR:
26115 case BMPDRAWSCREENCOMBOTR:
26116 case BMPBLIT:
26117 case BMPBLITTO:
26118 case BMPTILEBLIT:
26119 case BMPCOMBOBLIT:
26120 case BMPMODE7:
26121 case WRITEBITMAP:
26122 case CLEARBITMAP:
26123 case BITMAPCLEARTOCOLOR:
26124 case BMPFRAMER:
26125 case BMPWRITETILE:
26126 case BMPDITHER:
26127 case BMPREPLCOLOR:
26128 case BMPSHIFTCOLOR:
26129 case BMPMASKDRAW:
26130 case BMPMASKDRAW2:
26131 case BMPMASKDRAW3:
26132 case BMPMASKBLIT:
26133 case BMPMASKBLIT2:
26134 case BMPMASKBLIT3:
26135 65124359 do_drawing_command(scommand, false);
26136 65124359 break;
26137 case READBITMAP:
26138 {
26139 uint32_t bitref = SH::read_stack(ri->sp+2);
26140 SET_D(rEXP2, bitref);
26141 if(user_bitmap* b = checkBitmap(bitref,false,true))
26142 do_drawing_command(scommand, false);
26143 else //If the pointer isn't allocated, attempt to allocate it first
26144 {
26145 bitref = FFCore.get_free_bitmap();
26146 SET_D(rEXP2, bitref); //Return to ptr
26147 if(bitref) SH::write_stack(ri->sp+2,bitref); //Write the ref, for the drawing command to read
26148 else break; //No ref allocated; don't enqueue the drawing command.
26149 do_drawing_command(scommand, false);
26150 }
26151 break;
26152 }
26153 case REGENERATEBITMAP:
26154 {
26155 26757 int ref = SH::read_stack(ri->sp+3);
26156 26757 SET_D(rEXP2, ref);
26157
1/2
✓ Branch 0 taken 26757 times.
✗ Branch 1 not taken.
26757 if(user_bitmap* b = checkBitmap(ref,false,true))
26158 26757 do_drawing_command(scommand, false);
26159 else //If the pointer isn't allocated
26160 {
26161 int32_t w = SH::read_stack(ri->sp) / 10000;
26162 int32_t h = SH::read_stack(ri->sp+1) / 10000;
26163 if ( get_qr(qr_OLDCREATEBITMAP_ARGS) )
26164 {
26165 //flip height and width
26166 h = h ^ w;
26167 w = h ^ w;
26168 h = h ^ w;
26169 }
26170
26171 SET_D(rEXP2, FFCore.create_user_bitmap_ex(h,w)); //Return to ptr
26172 }
26173 26757 break;
26174 }
26175
26176 case BITMAPFREE:
26177 {
26178 3512 FFCore.do_deallocate_bitmap();
26179 3512 break;
26180 }
26181
26182 case BITMAPOWN:
26183 {
26184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
146 if(FFCore.isSystemBitref(GET_REF(bitmapref)))
26185 break; //Don't attempt to own system bitmaps!
26186
26187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
146 if (auto bitmap = checkBitmap(GET_REF(bitmapref), false))
26188 146 own_script_object(bitmap, type, i);
26189 146 break;
26190 }
26191
26192 case OBJ_OWN_BITMAP:
26193 {
26194 int bmpid = get_register(sarg1);
26195 if(FFCore.isSystemBitref(bmpid))
26196 break; //Don't attempt to own system bitmaps!
26197 user_bitmap* b = checkBitmap(bmpid, false);
26198 if(!b) break;
26199 ScriptType own_type = (ScriptType)sarg2;
26200 sprite* own_sprite = get_own_sprite(own_type);
26201 own_script_object(b, own_sprite);
26202 break;
26203 }
26204 case OBJ_OWN_PALDATA:
26205 {
26206 int palid = get_register(sarg1);
26207 user_paldata* pd = checkPalData(palid, false);
26208 if(!pd) break;
26209 ScriptType own_type = (ScriptType)sarg2;
26210 sprite* own_sprite = get_own_sprite(own_type);
26211 own_script_object(pd, own_sprite);
26212 break;
26213 }
26214 case OBJ_OWN_FILE:
26215 {
26216 int fileid = get_register(sarg1);
26217 user_file* f = checkFile(fileid, false);
26218 if(!f) break;
26219 ScriptType own_type = (ScriptType)sarg2;
26220 sprite* own_sprite = get_own_sprite(own_type);
26221 own_script_object(f, own_sprite);
26222 break;
26223 }
26224 case OBJ_OWN_DIR:
26225 {
26226 int dirid = get_register(sarg1);
26227 user_dir* dr = checkDir(dirid, false);
26228 if(!dr) break;
26229 ScriptType own_type = (ScriptType)sarg2;
26230 sprite* own_sprite = get_own_sprite(own_type);
26231 own_script_object(dr, own_sprite);
26232 break;
26233 }
26234 case OBJ_OWN_STACK:
26235 {
26236 int stackid = get_register(sarg1);
26237 user_stack* st = checkStack(stackid, false);
26238 if(!st) break;
26239 ScriptType own_type = (ScriptType)sarg2;
26240 sprite* own_sprite = get_own_sprite(own_type);
26241 own_script_object(st, own_sprite);
26242 break;
26243 }
26244 case OBJ_OWN_RNG:
26245 {
26246 int rngid = get_register(sarg1);
26247 user_rng* r = checkRNG(rngid, false);
26248 if(!r) break;
26249 ScriptType own_type = (ScriptType)sarg2;
26250 sprite* own_sprite = get_own_sprite(own_type);
26251 own_script_object(r, own_sprite);
26252 break;
26253 }
26254 case OBJ_OWN_ARRAY:
26255 {
26256 int arrid = get_register(sarg1);
26257 ScriptType own_type = (ScriptType)sarg2;
26258 sprite* own_sprite = get_own_sprite(own_type);
26259 do_own_array(arrid, own_sprite);
26260 break;
26261 }
26262
26263 case COPYTILEVV:
26264 do_copytile(true, true);
26265 break;
26266
26267 case COPYTILEVR:
26268 do_copytile(true, false);
26269 break;
26270
26271 case COPYTILERV:
26272 do_copytile(false, true);
26273 break;
26274
26275 case COPYTILERR:
26276 49289145 do_copytile(false, false);
26277 49289145 break;
26278
26279 case SWAPTILEVV:
26280 do_swaptile(true, true);
26281 break;
26282
26283 case SWAPTILEVR:
26284 do_swaptile(true, false);
26285 break;
26286
26287 case SWAPTILERV:
26288 do_swaptile(false, true);
26289 break;
26290
26291 case SWAPTILERR:
26292 do_swaptile(false, false);
26293 break;
26294
26295 case CLEARTILEV:
26296 do_cleartile(true);
26297 break;
26298
26299 case CLEARTILER:
26300 10 do_cleartile(false);
26301 10 break;
26302
26303 case OVERLAYTILEVV:
26304 do_overlaytile(true, true);
26305 break;
26306
26307 case OVERLAYTILEVR:
26308 do_overlaytile(true, false);
26309 break;
26310
26311 case OVERLAYTILERV:
26312 do_overlaytile(false, true);
26313 break;
26314
26315 case OVERLAYTILERR:
26316 57032 do_overlaytile(false, false);
26317 57032 break;
26318
26319 case FLIPROTTILEVV:
26320 do_fliprotatetile(true, true);
26321 break;
26322
26323 case FLIPROTTILEVR:
26324 do_fliprotatetile(true, false);
26325 break;
26326
26327 case FLIPROTTILERV:
26328 do_fliprotatetile(false, true);
26329 break;
26330
26331 case FLIPROTTILERR:
26332 do_fliprotatetile(false, false);
26333 break;
26334
26335 case GETTILEPIXEL:
26336 do_gettilepixel();
26337 break;
26338
26339 case SETTILEPIXEL:
26340 do_settilepixel();
26341 break;
26342
26343 case SHIFTTILEVV:
26344 do_shifttile(true, true);
26345 break;
26346
26347 case SHIFTTILEVR:
26348 do_shifttile(true, false);
26349 break;
26350
26351 case SHIFTTILERV:
26352 do_shifttile(false, true);
26353 break;
26354
26355 case SHIFTTILERR:
26356 do_shifttile(false, false);
26357 break;
26358
26359 case SETRENDERTARGET:
26360 7084216 do_set_rendertarget(true);
26361 7084216 break;
26362
26363 case GAMEEND:
26364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if ( using_SRAM )
26365 {
26366 Z_scripterrlog("Cannot End Game while reading or writing to SRAM. Aborting End. /n");
26367 break;
26368 }
26369 4 Quit = qQUIT;
26370 4 skipcont = 1;
26371 4 scommand = 0xFFFF;
26372 4 break;
26373 case GAMEEXIT:
26374 40 Quit = qEXIT;
26375 40 skipcont = 1;
26376 40 scommand = 0xFFFF;
26377 40 break;
26378 case GAMERELOAD:
26379
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if ( using_SRAM )
26380 {
26381 Z_scripterrlog("Cannot Reload Game while reading or writing to SRAM. Aborting Reload. /n");
26382 break;
26383 }
26384 9 Quit = qRELOAD;
26385 9 skipcont = 1;
26386 9 scommand = 0xFFFF;
26387 9 break;
26388 case GAMESETCUSTOMCURSOR:
26389 {
26390 int32_t bmpptr = SH::read_stack(ri->sp + 4);
26391 int fx = SH::read_stack(ri->sp + 3) / 10000;
26392 int fy = SH::read_stack(ri->sp + 2) / 10000;
26393 bool recolor = SH::read_stack(ri->sp + 1)!=0;
26394 bool scale = SH::read_stack(ri->sp + 0)!=0;
26395 if(user_bitmap* b = checkBitmap(bmpptr,true))
26396 {
26397 custom_mouse(b->u_bmp,fx,fy,recolor,scale);
26398 }
26399 break;
26400 }
26401 case CURRENTITEMID:
26402 {
26403 11953 int ity = SH::read_stack(ri->sp + 1) / 10000;
26404 11953 int flags = SH::read_stack(ri->sp + 0) / 10000;
26405 11953 bool checkcost = flags&0x01;
26406 11953 bool checkjinx = flags&0x02;
26407 11953 bool check_bunny = flags&0x04;
26408 11953 SET_D(rEXP1, current_item_id(ity,checkcost,checkjinx,check_bunny) * 10000);
26409 11953 break;
26410 }
26411
26412 case GAMECONTINUE:
26413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( using_SRAM )
26414 {
26415 Z_scripterrlog("Cannot Continue Game while reading or writing to SRAM. Aborting Continue. /n");
26416 break;
26417 }
26418 2 reset_all_combo_animations();
26419
26420 2 Quit = qCONT;
26421 2 skipcont = 1;
26422 //cont_game();
26423 2 scommand = 0xFFFF;
26424 2 break;
26425
26426 case GAMESAVEQUIT:
26427 if ( using_SRAM )
26428 {
26429 Z_scripterrlog("Cannot Save Game while reading or writing to SRAM. Aborting Save. /n");
26430 break;
26431 }
26432 Quit = qSAVE;
26433 skipcont = 1;
26434 scommand =0xFFFF;
26435 break;
26436
26437 case GAMESAVECONTINUE:
26438 Quit = qSAVECONT;
26439 skipcont = 1;
26440 scommand =0xFFFF;
26441 break;
26442
26443 case SAVE:
26444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if ( using_SRAM )
26445 {
26446 Z_scripterrlog("Cannot Save Game while reading or writing to SRAM. Aborting Save. /n");
26447 break;
26448 }
26449
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if(scriptCanSave)
26450 {
26451 30 save_game(false);
26452 30 scriptCanSave=false;
26453 30 }
26454 30 break;
26455
26456 case SAVESCREEN:
26457 do_showsavescreen();
26458 break;
26459
26460 case SHOWF6SCREEN:
26461 onTryQuit();
26462 break;
26463
26464 case SAVEQUITSCREEN:
26465 save_game(false, 1);
26466 break;
26467
26468 //Not Implemented
26469 case ELLIPSE2:
26470 case FLOODFILL:
26471 break;
26472
26473 //Visual Effects
26474 case WAVYIN:
26475 FFScript::do_wavyin();
26476 break;
26477 case WAVYOUT:
26478 FFScript::do_wavyout();
26479 break;
26480 case ZAPIN:
26481 FFScript::do_zapin();
26482 break;
26483 case ZAPOUT:
26484 FFScript::do_zapout();
26485 break;
26486 case OPENWIPE:
26487 {
26488 FFScript::do_openscreen();
26489 break;
26490 }
26491 case CLOSEWIPE:
26492 {
26493 FFScript::do_closescreen();
26494 break;
26495 }
26496 case OPENWIPESHAPE:
26497 {
26498 FFScript::do_openscreenshape();
26499 break;
26500 }
26501 case CLOSEWIPESHAPE:
26502 {
26503 FFScript::do_closescreenshape();
26504 break;
26505 }
26506
26507 case TINT:
26508 {
26509 3560 FFCore.Tint();
26510 3560 break;
26511 }
26512
26513 case CLEARTINT:
26514 {
26515 66 FFCore.clearTint();
26516 66 break;
26517 }
26518
26519 case MONOHUE:
26520 {
26521 FFCore.gfxmonohue();
26522 break;
26523 }
26524
26525 case SCREENDOSPAWN:
26526 {
26527 14 SET_D(rEXP1, scriptloadenemies(GET_REF(screenref)) ? 10000 : 0);
26528 14 break;
26529 }
26530
26531 case SCRTRIGGERCOMBO:
26532 {
26533 int32_t lyr = get_register(sarg1) / 10000;
26534 int32_t pos = get_register(sarg2) / 10000;
26535 rpos_t rpos = (rpos_t)pos;
26536 if (BC::checkComboRpos(rpos) != SH::_NoError)
26537 {
26538 break;
26539 }
26540
26541 set_register(sarg1, do_trigger_combo(get_rpos_handle(rpos, lyr), 0) ? 10000 : 0);
26542 break;
26543 }
26544 case SCRTRIGGERCOMBO2:
26545 {
26546 int32_t lyr = get_register(sarg1) / 10000;
26547 int32_t pos = get_register(sarg2) / 10000;
26548 int32_t idx = get_register(sarg3) / 10000;
26549 rpos_t rpos = (rpos_t)pos;
26550 if (BC::checkComboRpos(rpos) != SH::_NoError)
26551 break;
26552
26553 set_register(sarg1, do_trigger_combo(get_rpos_handle(rpos, lyr), idx) ? 10000 : 0);
26554 break;
26555 }
26556
26557 case SWITCHNPC:
26558 {
26559 byte effect = vbound(get_register(sarg1)/10000, 0, 255);
26560 set_register(sarg1,0);
26561 if(Hero.switchhookclk) break; //Already switching!
26562 if(GuyH::loadNPC(GET_REF(npcref)) == SH::_NoError)
26563 {
26564 switching_object = guys.getByUID(GET_REF(npcref));
26565 hooked_comborpos = rpos_t::None;
26566 hooked_layerbits = 0;
26567 switching_object->switch_hooked = true;
26568 Hero.doSwitchHook(effect);
26569 set_register(sarg1,10000);
26570 }
26571 break;
26572 }
26573
26574 case SWITCHITM:
26575 {
26576 byte effect = vbound(get_register(sarg1)/10000, 0, 255);
26577 set_register(sarg1,0);
26578 if(Hero.switchhookclk) break; //Already switching!
26579 if(ItemH::loadItem(GET_REF(itemref)) == SH::_NoError)
26580 {
26581 switching_object = ItemH::getItem();
26582 hooked_comborpos = rpos_t::None;
26583 hooked_layerbits = 0;
26584 switching_object->switch_hooked = true;
26585 Hero.doSwitchHook(effect);
26586 set_register(sarg1,10000);
26587 }
26588 break;
26589 }
26590
26591 case SWITCHLW:
26592 {
26593 byte effect = vbound(get_register(sarg1)/10000, 0, 255);
26594 set_register(sarg1,0);
26595 if(Hero.switchhookclk) break; //Already switching!
26596 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
26597 {
26598 switching_object = LwpnH::getWeapon();
26599 hooked_comborpos = rpos_t::None;
26600 hooked_layerbits = 0;
26601 switching_object->switch_hooked = true;
26602 Hero.doSwitchHook(effect);
26603 set_register(sarg1,10000);
26604 }
26605 break;
26606 }
26607
26608 case SWITCHEW:
26609 {
26610 byte effect = vbound(get_register(sarg1)/10000, 0, 255);
26611 set_register(sarg1,0);
26612 if(Hero.switchhookclk) break; //Already switching!
26613 if(EwpnH::loadWeapon(GET_REF(ewpnref)) == SH::_NoError)
26614 {
26615 switching_object = EwpnH::getWeapon();
26616 hooked_comborpos = rpos_t::None;
26617 hooked_layerbits = 0;
26618 switching_object->switch_hooked = true;
26619 Hero.doSwitchHook(effect);
26620 set_register(sarg1,10000);
26621 }
26622 break;
26623 }
26624
26625 case SWITCHCMB:
26626 {
26627 rpos_t rpos = (rpos_t)(get_register(sarg1)/10000);
26628 set_register(sarg1,0);
26629 if(Hero.switchhookclk) break; //Already switching!
26630 if (!is_valid_rpos(rpos))
26631 break;
26632 switching_object = NULL;
26633 hooked_comborpos = rpos;
26634 hooked_layerbits = 0;
26635 Hero.doSwitchHook(get_register(sarg2)/10000);
26636 if(!hooked_layerbits) //failed
26637 Hero.reset_hookshot();
26638 else set_register(sarg1,10000); //success return
26639 break;
26640 }
26641
26642 case LINKWARPEXR:
26643 {
26644 100 FFCore.do_warp_ex(false);
26645 100 break;
26646 }
26647
26648 case KILLPLAYER:
26649 {
26650 Hero.kill(get_register(sarg1));
26651 break;
26652 }
26653
26654 case HEROMOVEXY:
26655 {
26656 1798 zfix dx = zslongToFix(SH::read_stack(ri->sp + 4));
26657 1798 zfix dy = zslongToFix(SH::read_stack(ri->sp + 3));
26658 1798 bool kb = SH::read_stack(ri->sp + 2)!=0;
26659 1798 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26660 1798 bool shove = SH::read_stack(ri->sp + 0)!=0;
26661 1798 SET_D(rEXP1, Hero.movexy(dx, dy, kb, ign_sv, shove) ? 10000 : 0);
26662 1798 break;
26663 }
26664 case HEROCANMOVEXY:
26665 {
26666 3596 zfix dx = zslongToFix(SH::read_stack(ri->sp + 4));
26667 3596 zfix dy = zslongToFix(SH::read_stack(ri->sp + 3));
26668 3596 bool kb = SH::read_stack(ri->sp + 2)!=0;
26669 3596 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26670 3596 bool shove = SH::read_stack(ri->sp + 0)!=0;
26671 3596 SET_D(rEXP1, Hero.can_movexy(dx, dy, kb, ign_sv, shove) ? 10000 : 0);
26672 3596 break;
26673 }
26674 case HEROMOVEATANGLE:
26675 {
26676 zfix degrees = zslongToFix(SH::read_stack(ri->sp + 4));
26677 zfix pxamnt = zslongToFix(SH::read_stack(ri->sp + 3));
26678 bool kb = SH::read_stack(ri->sp + 2)!=0;
26679 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26680 bool shove = SH::read_stack(ri->sp + 0)!=0;
26681 SET_D(rEXP1, Hero.moveAtAngle(degrees, pxamnt, kb, ign_sv, shove) ? 10000 : 0);
26682 break;
26683 }
26684 case HEROCANMOVEATANGLE:
26685 {
26686 zfix degrees = zslongToFix(SH::read_stack(ri->sp + 4));
26687 zfix pxamnt = zslongToFix(SH::read_stack(ri->sp + 3));
26688 bool kb = SH::read_stack(ri->sp + 2)!=0;
26689 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26690 bool shove = SH::read_stack(ri->sp + 0)!=0;
26691 SET_D(rEXP1, Hero.can_moveAtAngle(degrees, pxamnt, kb, ign_sv, shove) ? 10000 : 0);
26692 break;
26693 }
26694 case HEROMOVE:
26695 {
26696 int dir = SH::read_stack(ri->sp + 4)/10000;
26697 zfix pxamnt = zslongToFix(SH::read_stack(ri->sp + 3));
26698 bool kb = SH::read_stack(ri->sp + 2)!=0;
26699 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26700 bool shove = SH::read_stack(ri->sp + 0)!=0;
26701 SET_D(rEXP1, Hero.moveDir(dir, pxamnt, kb, ign_sv, shove) ? 10000 : 0);
26702 break;
26703 }
26704 case HEROCANMOVE:
26705 {
26706 440764 int dir = SH::read_stack(ri->sp + 4)/10000;
26707 440764 zfix pxamnt = zslongToFix(SH::read_stack(ri->sp + 3));
26708 440764 bool kb = SH::read_stack(ri->sp + 2)!=0;
26709 440764 bool ign_sv = SH::read_stack(ri->sp + 1)!=0;
26710 440764 bool shove = SH::read_stack(ri->sp + 0)!=0;
26711 440764 SET_D(rEXP1, Hero.can_moveDir(dir, pxamnt, kb, ign_sv, shove) ? 10000 : 0);
26712 440764 break;
26713 }
26714 case HEROLIFTRELEASE:
26715 {
26716 if(Hero.lift_wpn)
26717 {
26718 SET_D(rEXP1, Hero.lift_wpn->getUID());
26719 Lwpns.add(Hero.lift_wpn);
26720 Hero.lift_wpn = nullptr;
26721 }
26722 else SET_D(rEXP1, 0);
26723 break;
26724 }
26725 case HEROLIFTGRAB:
26726 {
26727 auto lwuid = SH::read_stack(ri->sp + 2);
26728 auto lifttime = SH::read_stack(ri->sp + 1)/10000;
26729 auto liftheight = zslongToFix(SH::read_stack(ri->sp + 0));
26730 if(weapon* wpn = checkLWpn(lwuid))
26731 {
26732 Hero.lift(wpn, lifttime, liftheight);
26733 if(Lwpns.find(wpn) > -1)
26734 Lwpns.remove(wpn);
26735 if(type == ScriptType::Lwpn && lwuid == i)
26736 earlyretval = RUNSCRIPT_SELFREMOVE;
26737 }
26738 break;
26739 }
26740 case HEROISFLICKERFRAME:
26741 SET_D(rEXP1, Hero.is_hitflickerframe() ? 10000 : 0);
26742 break;
26743 case LOADPORTAL:
26744 {
26745 auto val = get_register(sarg1)/10000;
26746 if(val != -1)
26747 {
26748 portal* prt = (portal*)portals.spr(val);
26749 if(prt)
26750 val = prt->getUID();
26751 else
26752 {
26753 Z_scripterrlog("Tried to load invalid portal index '%d'\n", val);
26754 val = 0;
26755 }
26756 }
26757 ri->portalref = SET_D(rEXP1, val);
26758 break;
26759 }
26760 case CREATEPORTAL:
26761 {
26762 portal* p = new portal();
26763 if(portals.add(p))
26764 ri->portalref = SET_D(rEXP1, p->getUID());
26765 else
26766 {
26767 ri->portalref = SET_D(rEXP1, 0);
26768 Z_scripterrlog("Unable to create new portal! Limit reached!\n");
26769 }
26770 break;
26771 }
26772 case LOADSAVPORTAL:
26773 {
26774 auto val = get_register(sarg1)/10000;
26775 savedportal* prt = checkSavedPortal(val);
26776 ri->savportalref = SET_D(rEXP1, prt ? val : 0);
26777 break;
26778 }
26779 case CREATESAVPORTAL:
26780 {
26781 if(game->user_portals.size() >= MAX_SAVED_PORTALS)
26782 {
26783 ri->savportalref = SET_D(rEXP1, 0);
26784 Z_scripterrlog("Cannot create any more Saved Portals! Remove some first!\n");
26785 break;
26786 }
26787 savedportal& ref = game->user_portals.emplace_back();
26788 ri->savportalref = SET_D(rEXP1, ref.getUID());
26789 break;
26790 }
26791 case PORTALREMOVE:
26792 {
26793 if(portal* p = checkPortal(GET_REF(portalref), true))
26794 {
26795 if(p == &mirror_portal)
26796 p->clear();
26797 else
26798 {
26799 auto id = portals.find(p);
26800 if(id > -1)
26801 portals.del(id,true);
26802 }
26803 }
26804 break;
26805 }
26806 case PORTALUSESPRITE:
26807 do_portalusesprite();
26808 break;
26809 case SAVEDPORTALREMOVE:
26810 {
26811 if(savedportal* sp = checkSavedPortal(GET_REF(savportalref), true))
26812 {
26813 if(sp == &(game->saved_mirror_portal))
26814 sp->clear();
26815 else
26816 {
26817 //ensure all pointers to the object are cleared before deleting
26818 portals.forEach([&](sprite& spr)
26819 {
26820 portal* tmp = (portal*)&spr;
26821 if(sp->getUID() == tmp->saved_data)
26822 {
26823 tmp->saved_data = 0;
26824 }
26825 return false;
26826 });
26827 //delete the savedportal object from the vector
26828 for(auto it = game->user_portals.begin();
26829 it != game->user_portals.end();)
26830 {
26831 savedportal& tmp = *it;
26832 if(sp == &tmp)
26833 {
26834 game->user_portals.erase(it);
26835 break;
26836 }
26837 else ++it;
26838 }
26839 }
26840 }
26841 break;
26842 }
26843 case SAVEDPORTALGENERATE:
26844 {
26845 auto retval = 0;
26846 if(savedportal* sp = checkSavedPortal(GET_REF(savportalref)))
26847 {
26848 retval = getPortalFromSaved(sp);
26849 if(!retval)
26850 {
26851 if(portal* p = loadportal(*sp))
26852 if(portals.add(p))
26853 retval = p->getUID();
26854 }
26855 }
26856 SET_D(rEXP1, retval);
26857 break;
26858 }
26859
26860 case LINKEXPLODER:
26861 {
26862 int32_t mode = get_register(sarg1) / 10000;
26863 if ( (unsigned) mode > 2 )
26864 {
26865 Z_scripterrlog("Invalid mode (%d) passed to Hero->Explode(int32_t mode)\n",mode);
26866 }
26867 else Hero.explode(mode);
26868 break;
26869 }
26870 case NPCEXPLODER:
26871 {
26872 int32_t mode = get_register(sarg1) / 10000;
26873 if ( (unsigned) mode > 2 )
26874 {
26875 Z_scripterrlog("Invalid mode (%d) passed to npc->Explode(int32_t mode)\n",mode);
26876 }
26877 else
26878 {
26879 if(GuyH::loadNPC(GET_REF(npcref)) == SH::_NoError)
26880 {
26881 GuyH::getNPC()->explode(mode);
26882 }
26883 }
26884 break;
26885 }
26886
26887 case ITEMEXPLODER:
26888 {
26889
26890 int32_t mode = get_register(sarg1) / 10000;
26891 if ( (unsigned) mode > 2 )
26892 {
26893 Z_scripterrlog("Invalid mode (%d) passed to item->Explode(int32_t mode)\n",mode);
26894 }
26895 else
26896 {
26897 if(ItemH::loadItem(GET_REF(itemref)) == SH::_NoError)
26898 {
26899 ItemH::getItem()->explode(mode);
26900 }
26901 }
26902 break;
26903 }
26904 case LWEAPONEXPLODER:
26905 {
26906 int32_t mode = get_register(sarg1) / 10000;
26907 if ( (unsigned) mode > 2 )
26908 {
26909 Z_scripterrlog("Invalid mode (%d) passed to lweapon->Explode(int32_t mode)\n",mode);
26910 }
26911 else
26912 {
26913 if(LwpnH::loadWeapon(GET_REF(lwpnref)) == SH::_NoError)
26914 {
26915 LwpnH::getWeapon()->explode(mode);
26916 }
26917 }
26918 break;
26919 }
26920 case EWEAPONEXPLODER:
26921 {
26922 int32_t mode = get_register(sarg1) / 10000;
26923 if ( (unsigned) mode > 2 )
26924 {
26925 Z_scripterrlog("Invalid mode (%d) passed to eweapon->Explode(int32_t mode)\n",mode);
26926 }
26927 else
26928 {
26929 if(EwpnH::loadWeapon(GET_REF(ewpnref)) == SH::_NoError)
26930 {
26931 EwpnH::getWeapon()->explode(mode);
26932 }
26933 }
26934 break;
26935 }
26936
26937 case BOTTLENAMEGET:
26938 {
26939 int32_t arrayptr = get_register(sarg1);
26940 int32_t id = GET_REF(bottletyperef)-1;
26941 if(unsigned(id) > 63)
26942 {
26943 Z_scripterrlog("Invalid bottledata ID (%d) passed to bottledata->GetName().\n", id);
26944 break;
26945 }
26946
26947 if(ArrayH::setArray(arrayptr, QMisc.bottle_types[id].name) == SH::_Overflow)
26948 Z_scripterrlog("Array supplied to 'bottledata->GetName()' not large enough\n");
26949 break;
26950 }
26951 case BOTTLENAMESET:
26952 {
26953 int32_t arrayptr = get_register(sarg1);
26954 int32_t id = GET_REF(bottletyperef)-1;
26955 if(unsigned(id) > 63)
26956 {
26957 Z_scripterrlog("Invalid bottledata ID (%d) passed to bottledata->SetName().\n", id+1);
26958 break;
26959 }
26960 string name;
26961 ArrayH::getString(arrayptr, name, 31);
26962 strcpy(QMisc.bottle_types[id].name, name.c_str());
26963 break;
26964 }
26965 case BSHOPNAMEGET:
26966 {
26967 int32_t arrayptr = get_register(sarg1);
26968 int32_t id = GET_REF(bottleshopref)-1;
26969 if(unsigned(id) > 255)
26970 {
26971 Z_scripterrlog("Invalid bottleshopdata ID (%d) passed to bottleshopdata->GetName().\n", id+1);
26972 break;
26973 }
26974
26975 if(ArrayH::setArray(arrayptr, QMisc.bottle_shop_types[id].name) == SH::_Overflow)
26976 Z_scripterrlog("Array supplied to 'bottleshopdata->GetName()' not large enough\n");
26977 break;
26978 }
26979 case BSHOPNAMESET:
26980 {
26981 int32_t arrayptr = get_register(sarg1);
26982 int32_t id = GET_REF(bottleshopref);
26983 if(unsigned(id) > 255)
26984 {
26985 Z_scripterrlog("Invalid bottleshopdata ID (%d) passed to bottleshopdata->SetName().\n", id);
26986 break;
26987 }
26988 string name;
26989 ArrayH::getString(arrayptr, name, 31);
26990 strcpy(QMisc.bottle_shop_types[id].name, name.c_str());
26991 break;
26992 }
26993
26994 case RUNITEMSCRIPT:
26995 {
26996 15 int32_t itemid = GET_REF(itemdataref);
26997
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if(unsigned(itemid) > MAXITEMS) break;
26998 15 int32_t mode = get_register(sarg1) / 10000;
26999 15 auto& data = get_script_engine_data(ScriptType::Item, itemid);
27000
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
15 switch(mode)
27001 {
27002 case 0:
27003 {
27004 data.doscript = 4;
27005 break;
27006 }
27007 case 1:
27008 {
27009 if ( itemsbuf[itemid].script != 0 ) //&& !data.doscript )
27010 {
27011 if ( !data.doscript )
27012 {
27013 data.clear_ref();
27014 data.doscript = 1;
27015 //ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[itemid].script, itemid);
27016 }
27017 else
27018 {
27019 //Emily, clear the stack here, clear refinfo, and set up to run again on the next frame from the beginning.
27020 }
27021 }
27022 break;
27023 }
27024 15 case 2:
27025 default:
27026 {
27027
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if ( itemsbuf[itemid].script != 0 ) //&& !data.doscript )
27028 {
27029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (data.doscript != 2 )data.doscript = 2;
27030 15 }
27031 15 break;
27032 }
27033 /*
27034 case 0:
27035 {
27036 data.doscript = 0;
27037 break;
27038 }
27039 default:
27040 {
27041
27042 if ( itemsbuf[itemid].script != 0 ) //&& !data.doscript )
27043 {
27044 //itemScriptData[itemid].Clear();
27045 //for ( int32_t q = 0; q < 1024; q++ ) item_stack[itemid][q] = 0;
27046 //ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[itemid].script, itemid & 0xFFF);
27047 data.doscript = 2;
27048 }
27049 break;
27050 }
27051 */
27052 }
27053 15 break;
27054 }
27055
27056 //Game over Screen
27057 case SETCONTINUESCREEN: FFScript::FFChangeSubscreenText(); break;
27058 case SETCONTINUESTRING: FFScript::FFSetSaveScreenSetting(); break;
27059
27060 case LWPNDEL:
27061 {
27062
3/4
✓ Branch 0 taken 2509 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2509 times.
2511 if(type == ScriptType::Lwpn && ri->lwpnref == i)
27063 {
27064 2509 FFCore.do_lweapon_delete();
27065 2509 return RUNSCRIPT_SELFDELETE;
27066 }
27067
27068 2 FFCore.do_lweapon_delete();
27069 2 break;
27070 }
27071 case EWPNDEL:
27072 {
27073
3/4
✓ Branch 0 taken 1438 times.
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 1438 times.
✗ Branch 3 not taken.
1482 if(type == ScriptType::Ewpn && ri->ewpnref == i)
27074 {
27075 1438 FFCore.do_eweapon_delete();
27076 1438 return RUNSCRIPT_SELFDELETE;
27077 }
27078
27079 44 FFCore.do_eweapon_delete();
27080 44 break;
27081 }
27082
27083 case PLAYENHMUSICEX:
27084 // DEPRECATED
27085 do_enh_music(false);
27086 break;
27087
27088 case GETENHMUSICPOS:
27089 FFCore.do_get_music_position();
27090 break;
27091
27092 case SETENHMUSICPOS:
27093 FFCore.do_set_music_position(false);
27094 break;
27095
27096 case SETENHMUSICSPEED:
27097 FFCore.do_set_music_speed(false);
27098 break;
27099
27100 case GETENHMUSICLEN:
27101 FFCore.do_get_music_length();
27102 break;
27103
27104 case SETENHMUSICLOOP:
27105 3 FFCore.do_set_music_loop();
27106 3 break;
27107
27108 case ENHCROSSFADE:
27109 5 do_enh_music_crossfade();
27110 5 break;
27111
27112 case DIREXISTS:
27113 FFCore.do_checkdir(true);
27114 break;
27115
27116 case FILEEXISTS:
27117 FFCore.do_checkdir(false);
27118 break;
27119
27120 case FILESYSREMOVE:
27121 FFCore.do_fs_remove();
27122 break;
27123
27124 case TOBYTE:
27125 do_tobyte();
27126 break;
27127 case TOWORD:
27128 do_toword();
27129 break;
27130 case TOSHORT: do_toshort(); break;
27131 case TOSIGNEDBYTE: do_tosignedbyte(); break;
27132 case TOINTEGER: do_tointeger(); break;
27133 case CEILING: do_ceiling(); break;
27134 case FLOOR: do_floor(); break;
27135 case TRUNCATE: do_trunc(); break;
27136 case ROUND: do_round(); break;
27137 case ROUNDAWAY: do_roundaway(); break;
27138
27139 //Stack
27140 case STACKFREE:
27141 {
27142 if(user_stack* st = checkStack(GET_REF(stackref), true))
27143 {
27144 free_script_object(st->id);
27145 }
27146 break;
27147 }
27148 case STACKOWN:
27149 {
27150 if(user_stack* st = checkStack(GET_REF(stackref)))
27151 {
27152 own_script_object(st, type, i);
27153 }
27154 break;
27155 }
27156 case STACKCLEAR:
27157 {
27158 if(user_stack* st = checkStack(GET_REF(stackref)))
27159 {
27160 st->clearStack();
27161 }
27162 break;
27163 }
27164 case STACKGET:
27165 {
27166 if(user_stack* st = checkStack(GET_REF(stackref), true))
27167 {
27168 int32_t indx = get_register(sarg1); //NOT /10000
27169 set_register(sarg1, st->get(indx)); //NOT *10000
27170 }
27171 else set_register(sarg1, 0L);
27172 break;
27173 }
27174 case STACKSET:
27175 {
27176 if(user_stack* st = checkStack(GET_REF(stackref), true))
27177 {
27178 int32_t indx = get_register(sarg1); //NOT /10000
27179 int32_t val = get_register(sarg2); //NOT /10000
27180 st->set(indx, val); //NOT *10000
27181 }
27182 break;
27183 }
27184 case STACKPOPBACK:
27185 {
27186 if(user_stack* st = checkStack(GET_REF(stackref), true))
27187 {
27188 set_register(sarg1, st->pop_back()); //NOT *10000
27189 }
27190 else set_register(sarg1, 0L);
27191 break;
27192 }
27193 case STACKPOPFRONT:
27194 {
27195 if(user_stack* st = checkStack(GET_REF(stackref), true))
27196 {
27197 set_register(sarg1, st->pop_front()); //NOT *10000
27198 }
27199 else set_register(sarg1, 0L);
27200 break;
27201 }
27202 case STACKPEEKBACK:
27203 {
27204 if(user_stack* st = checkStack(GET_REF(stackref), true))
27205 {
27206 set_register(sarg1, st->peek_back()); //NOT *10000
27207 }
27208 else set_register(sarg1, 0L);
27209 break;
27210 }
27211 case STACKPEEKFRONT:
27212 {
27213 if(user_stack* st = checkStack(GET_REF(stackref), true))
27214 {
27215 set_register(sarg1, st->peek_front()); //NOT *10000
27216 }
27217 else set_register(sarg1, 0L);
27218 break;
27219 }
27220 case STACKPUSHBACK:
27221 {
27222 if(user_stack* st = checkStack(GET_REF(stackref), true))
27223 {
27224 int32_t val = get_register(sarg1); //NOT /10000
27225 st->push_back(val);
27226 }
27227 break;
27228 }
27229 case STACKPUSHFRONT:
27230 {
27231 if(user_stack* st = checkStack(GET_REF(stackref), true))
27232 {
27233 int32_t val = get_register(sarg1); //NOT /10000
27234 st->push_front(val);
27235 }
27236 break;
27237 }
27238
27239 //Module
27240 case MODULEGETIC:
27241 {
27242
27243 int32_t buf_pointer = SH::get_arg(sarg1, false) / 10000;
27244 int32_t element = SH::get_arg(sarg2, false) / 10000;
27245
27246 if ( ((unsigned)element) > 511 )
27247 {
27248 Z_scripterrlog("Illegal itemclass supplied to ZInfo->GetItemClass().\nLegal values are 1 to 511.\n");
27249 }
27250 else
27251 {
27252 char buffer[256] = {0};
27253 strcpy(buffer,ZI.getItemClassName(element));
27254 buffer[255] = '\0';
27255 if(ArrayH::setArray(buf_pointer, buffer) == SH::_Overflow)
27256 {
27257 Z_scripterrlog("Dest string supplied to 'Module->GetItemClass()' is not large enough\n");
27258 }
27259 }
27260
27261 break;
27262 }
27263
27264 //{ Randgen Stuff
27265 case RNGRAND1:
27266 if(user_rng* r = checkRNG(GET_REF(rngref)))
27267 {
27268 SET_D(rEXP1, r->rand(214748, -214748)*10000L);
27269 }
27270 else SET_D(rEXP1, -10000L);
27271 break;
27272 case RNGRAND2:
27273
1/2
✓ Branch 0 taken 58074 times.
✗ Branch 1 not taken.
58074 if(user_rng* r = checkRNG(GET_REF(rngref)))
27274 {
27275 58074 set_register(sarg1,r->rand(get_register(sarg1)/10000L)*10000L);
27276 58074 }
27277 else set_register(sarg1,-10000L);
27278 58074 break;
27279 case RNGRAND3:
27280
1/2
✓ Branch 0 taken 463835 times.
✗ Branch 1 not taken.
463835 if(user_rng* r = checkRNG(GET_REF(rngref)))
27281 {
27282 463835 set_register(sarg1,r->rand(get_register(sarg1)/10000L, get_register(sarg2)/10000L)* 10000L);
27283 463835 }
27284 else set_register(sarg1,-10000L);
27285 463835 break;
27286 case RNGLRAND1:
27287 if(user_rng* r = checkRNG(GET_REF(rngref)))
27288 {
27289 SET_D(rEXP1, r->rand());
27290 }
27291 else SET_D(rEXP1, -10000L);
27292 break;
27293 case RNGLRAND2:
27294 if(user_rng* r = checkRNG(GET_REF(rngref)))
27295 {
27296 SET_D(rEXP1, r->rand(get_register(sarg1)));
27297 }
27298 else SET_D(rEXP1, -10000L);
27299 break;
27300 case RNGLRAND3:
27301 if(user_rng* r = checkRNG(GET_REF(rngref)))
27302 {
27303 SET_D(rEXP1, r->rand(get_register(sarg1), get_register(sarg2)));
27304 }
27305 else SET_D(rEXP1, -10000L);
27306 break;
27307 case RNGSEED:
27308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if(user_rng* r = checkRNG(GET_REF(rngref)))
27309 {
27310 73 r->srand(get_register(sarg1));
27311 73 }
27312 73 break;
27313 case RNGRSEED:
27314 if(user_rng* r = checkRNG(GET_REF(rngref)))
27315 {
27316 SET_D(rEXP1, r->srand());
27317 }
27318 else SET_D(rEXP1, -10000);
27319 break;
27320 case RNGFREE:
27321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(user_rng* r = checkRNG(GET_REF(rngref), true))
27322 {
27323 6 free_script_object(r->id);
27324 6 }
27325 6 break;
27326 case RNGOWN:
27327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if(user_rng* r = checkRNG(GET_REF(rngref), false))
27328 {
27329 8 own_script_object(r, type, i);
27330 8 }
27331 8 break;
27332 //}
27333 case LOADGENERICDATA:
27334 137138 FFCore.do_loadgenericdata(false); break;
27335 case RUNGENFRZSCR:
27336 {
27337 10 bool r = FFCore.runGenericFrozenEngine(word(GET_REF(genericdataref)));
27338 10 set_register(sarg1, r ? 10000L : 0L);
27339 10 break;
27340 }
27341
27342 ///----------------------------------------------------------------------------------------------------//
27343
27344 case SUBDATA_GET_NAME:
27345 {
27346 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
27347 {
27348 auto aptr = get_register(sarg1);
27349 if(ArrayH::setArray(aptr, sub->name, true) == SH::_Overflow)
27350 Z_scripterrlog("Array supplied to 'subscreendata->GetName()' not large enough,"
27351 " and couldn't be resized!\n");
27352 }
27353 break;
27354 }
27355 case SUBDATA_SET_NAME:
27356 {
27357 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
27358 {
27359 auto aptr = get_register(sarg1);
27360 ArrayH::getString(aptr, sub->name);
27361 }
27362 break;
27363 }
27364 case SUBDATA_SWAP_PAGES:
27365 {
27366 ri->subscreendataref = SH::read_stack(ri->sp+2);
27367 if(ZCSubscreen* sub = checkSubData(GET_REF(subscreendataref)))
27368 {
27369 int p1 = SH::read_stack(ri->sp+1) / 10000;
27370 int p2 = SH::read_stack(ri->sp+0) / 10000;
27371 if(unsigned(p1) >= sub->pages.size())
27372 Z_scripterrlog("Invalid page index '%d' passed to subscreendata->SwapPages()\n", p1);
27373 else if(unsigned(p2) >= sub->pages.size())
27374 Z_scripterrlog("Invalid page index '%d' passed to subscreendata->SwapPages()\n", p2);
27375 else sub->swap_pages(p1,p2);
27376 }
27377 break;
27378 }
27379 case SUBPAGE_SWAP_WIDG:
27380 {
27381 ri->subscreenpageref = SH::read_stack(ri->sp+2);
27382 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27383 {
27384 int p1 = SH::read_stack(ri->sp+1) / 10000;
27385 int p2 = SH::read_stack(ri->sp+0) / 10000;
27386 if(unsigned(p1) >= pg->size())
27387 Z_scripterrlog("Invalid page index '%d' passed to subscreenpage->SwapWidgets()\n", p1);
27388 else if(unsigned(p2) >= pg->size())
27389 Z_scripterrlog("Invalid page index '%d' passed to subscreenpage->SwapWidgets()\n", p2);
27390 else pg->swap_widg(p1,p2);
27391 }
27392 break;
27393 }
27394 case SUBPAGE_FIND_WIDGET:
27395 {
27396 14870 SET_D(rEXP1, 0);
27397
27398 14870 ri->subscreenpageref = SH::read_stack(ri->sp+1);
27399
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 14870 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14870 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 14870 times.
14870 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref), {sstACTIVE, sstMAP}))
27400 {
27401 14870 int cursorpos = SH::read_stack(ri->sp+0) / 10000;
27402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14870 times.
14870 if(auto* widg = pg->get_widg_pos(cursorpos,false))
27403 {
27404 14870 auto q = pg->widget_index(widg);
27405
1/2
✓ Branch 0 taken 14870 times.
✗ Branch 1 not taken.
14870 if(q > -1)
27406 {
27407 44610 auto [sub,ty,pgid,_ind] = from_subref(GET_REF(subscreenpageref));
27408 44610 SET_D(rEXP1, get_subref(sub,ty,pgid,q));
27409 14870 }
27410 14870 }
27411 14870 }
27412 14870 break;
27413 }
27414 case SUBPAGE_FIND_WIDGET_BY_LABEL:
27415 {
27416 17877 SET_D(rEXP1, 0);
27417
27418 17877 ri->subscreenpageref = SH::read_stack(ri->sp+1);
27419
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17877 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17877 times.
17877 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27420 {
27421 17877 int aptr = SH::read_stack(ri->sp+0);
27422 17877 std::string lbl;
27423
1/2
✓ Branch 0 taken 17877 times.
✗ Branch 1 not taken.
17877 ArrayH::getString(aptr, lbl);
27424
1/2
✓ Branch 0 taken 17877 times.
✗ Branch 1 not taken.
17877 if(lbl.size())
27425 {
27426
1/2
✓ Branch 0 taken 17877 times.
✗ Branch 1 not taken.
17877 auto q = pg->find_label_index(lbl);
27427
2/2
✓ Branch 0 taken 5703 times.
✓ Branch 1 taken 12174 times.
17877 if(q > -1)
27428 {
27429 36522 auto [sub,ty,pgid,_ind] = from_subref(GET_REF(subscreenpageref));
27430 36522 SET_D(rEXP1, get_subref(sub,ty,pgid,q));
27431 12174 }
27432 17877 }
27433 17877 }
27434 17877 break;
27435 }
27436 case SUBPAGE_MOVE_SEL:
27437 {
27438 #define SUBSEL_FLAG_NO_NONEQUIP 0x01
27439 #define SUBSEL_FLAG_NEED_ITEM 0x02
27440
27441 SET_D(rEXP1, 0);
27442
27443 ri->subscreenpageref = SH::read_stack(ri->sp+3);
27444 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27445 {
27446 int flags = SH::read_stack(ri->sp+0) / 10000;
27447 int dir = SH::read_stack(ri->sp+1) / 10000;
27448 int pos = SH::read_stack(ri->sp+2) / 10000;
27449 switch(dir)
27450 {
27451 case up:
27452 dir = SEL_UP;
27453 break;
27454 case down:
27455 dir = SEL_DOWN;
27456 break;
27457 case left:
27458 dir = SEL_LEFT;
27459 break;
27460 case right: default:
27461 dir = SEL_RIGHT;
27462 break;
27463 }
27464
27465 auto newpos = pg->movepos_legacy(dir, (pos<<8)|pg->getIndex(),
27466 255, 255, 255, flags&SUBSEL_FLAG_NO_NONEQUIP,
27467 flags&SUBSEL_FLAG_NEED_ITEM, true) >> 8;
27468 SET_D(rEXP1, 10000*newpos);
27469 }
27470 break;
27471 }
27472 case SUBPAGE_NEW_WIDG:
27473 {
27474 SET_D(rEXP1, 0);
27475
27476 ri->subscreenpageref = SH::read_stack(ri->sp+1);
27477 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27478 {
27479 if(pg->size() == 0x2000)
27480 break; //Page is full!
27481 int ty = SH::read_stack(ri->sp+0) / 10000;
27482 if(auto* widg = SubscrWidget::newType(ty))
27483 {
27484 widg->posflags = sspUP | sspDOWN | sspSCROLLING;
27485 widg->w = 1;
27486 widg->h = 1;
27487 pg->push_back(widg);
27488 auto [sub,ty,pgid,_ind] = from_subref(GET_REF(subscreenpageref));
27489 SET_D(rEXP1, get_subref(sub,ty,pgid,pg->size()-1));
27490 }
27491 else Z_scripterrlog("Invalid type %d passed to subscreenpage->CreateWidget()\n",ty);
27492 }
27493 break;
27494 }
27495 case SUBPAGE_DELETE:
27496 {
27497 if(SubscrPage* pg = checkSubPage(GET_REF(subscreenpageref)))
27498 {
27499 auto [sub,_ty] = load_subdata(GET_REF(subscreenpageref));
27500 sub->delete_page(pg->getIndex());
27501 }
27502 break;
27503 }
27504 case SUBWIDG_GET_SELTEXT_OVERRIDE:
27505 {
27506 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27507 {
27508 auto aptr = get_register(sarg1);
27509 if(ArrayH::setArray(aptr, widg->override_text, true) == SH::_Overflow)
27510 Z_scripterrlog("Array supplied to 'subscreenwidget->GetSelTextOverride()' not large enough,"
27511 " and couldn't be resized!\n");
27512 }
27513 break;
27514 }
27515 case SUBWIDG_SET_SELTEXT_OVERRIDE:
27516 {
27517 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27518 {
27519 auto aptr = get_register(sarg1);
27520 ArrayH::getString(aptr, widg->override_text);
27521 }
27522 break;
27523 }
27524 case SUBWIDG_GET_LABEL:
27525 {
27526
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 828 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 828 times.
828 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27527 {
27528 828 auto aptr = get_register(sarg1);
27529
1/2
✓ Branch 0 taken 828 times.
✗ Branch 1 not taken.
828 if(ArrayH::setArray(aptr, widg->label, true) == SH::_Overflow)
27530 Z_scripterrlog("Array supplied to 'subscreenwidget->GetLabel()' not large enough,"
27531 " and couldn't be resized!\n");
27532 828 }
27533 828 break;
27534 }
27535 case SUBWIDG_SET_LABEL:
27536 {
27537 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27538 {
27539 auto aptr = get_register(sarg1);
27540 ArrayH::getString(aptr, widg->label);
27541 }
27542 break;
27543 }
27544 case SUBWIDG_CHECK_CONDITIONS:
27545 {
27546 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27547 {
27548 set_register(sarg1, widg->check_conditions() ? 10000 : 0);
27549 }
27550 break;
27551 }
27552 case SUBWIDG_CHECK_VISIBLE:
27553 {
27554 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27555 {
27556 extern int current_subscr_pos;
27557 set_register(sarg1, widg->visible(current_subscr_pos, game->should_show_time()) ? 10000 : 0);
27558 }
27559 break;
27560 }
27561 case SUBWIDG_TY_GETTEXT:
27562 {
27563 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27564 {
27565 optional<string> str;
27566 byte ty = widg->getType();
27567 switch(ty)
27568 {
27569 case widgTEXT:
27570 str = ((SW_Text*)widg)->text;
27571 break;
27572 case widgTEXTBOX:
27573 str = ((SW_TextBox*)widg)->text;
27574 break;
27575 case widgITMCOOLDOWNTEXT:
27576 str = ((SW_ItemCooldownText*)widg)->get_text();
27577 break;
27578 default:
27579 bad_subwidg_type(true, ty);
27580 break;
27581 }
27582 if(str)
27583 {
27584 auto aptr = get_register(sarg1);
27585 if(ArrayH::setArray(aptr, *str, true) == SH::_Overflow)
27586 Z_scripterrlog("Array supplied to 'subscreenwidget->GetText()' not large enough,"
27587 " and couldn't be resized!\n");
27588 }
27589 }
27590 break;
27591 }
27592 case SUBWIDG_TY_SETTEXT:
27593 {
27594
2/4
✓ Branch 0 taken 76234 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 76234 times.
76234 if(SubscrWidget* widg = checkSubWidg(GET_REF(subscreenwidgref)))
27595 {
27596 76234 std::string* str = nullptr;
27597 76234 byte ty = widg->getType();
27598
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 68852 times.
✓ Branch 2 taken 7382 times.
76234 switch(ty)
27599 {
27600 case widgTEXT:
27601 68852 str = &((SW_Text*)widg)->text;
27602 68852 break;
27603 case widgTEXTBOX:
27604 7382 str = &((SW_TextBox*)widg)->text;
27605 7382 break;
27606 default:
27607 bad_subwidg_type(true, ty);
27608 break;
27609 }
27610
1/2
✓ Branch 0 taken 76234 times.
✗ Branch 1 not taken.
76234 if(str)
27611 {
27612 76234 auto aptr = get_register(sarg1);
27613 76234 ArrayH::getString(aptr, *str);
27614 76234 }
27615 76234 }
27616 76234 break;
27617 }
27618
27619 case COMBOD_GET_TRIGGER:
27620 {
27621 if(checkComboRef())
27622 {
27623 auto aptr = get_register(sarg1) / 10000;
27624 string name;
27625 ArrayH::getString(aptr, name, 256);
27626 newcombo const& cmb = combobuf[GET_REF(combodataref)];
27627 int32_t ret = 0;
27628 for(size_t idx = 0; idx < cmb.triggers.size(); ++idx)
27629 {
27630 if(cmb.triggers[idx].label == name)
27631 {
27632 ret = dword(GET_REF(combodataref)) | (dword(idx)<<24);
27633 break;
27634 }
27635 }
27636
27637 set_register(sarg1, ret);
27638 }
27639 break;
27640 }
27641 case CMBTRIG_GET_LABEL:
27642 {
27643 if(auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
27644 {
27645 auto aptr = get_register(sarg1) / 10000;
27646 if(ArrayH::setArray(aptr, trig->label, true) == SH::_Overflow)
27647 Z_scripterrlog("Array supplied to 'combotrigger->GetLabel()' not large enough,"
27648 " and couldn't be resized!\n");
27649 }
27650 break;
27651 }
27652 case CMBTRIG_SET_LABEL:
27653 {
27654 if (auto* trig = get_combo_trigger(GET_REF(combotriggerref)))
27655 {
27656 auto aptr = get_register(sarg1) / 10000;
27657 ArrayH::getString(aptr, trig->label);
27658 }
27659 break;
27660 }
27661
27662 case REF_INC:
27663 {
27664 1578099 int offset = GET_D(rSFRAME) + sarg1;
27665
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1578099 times.
1578099 if (!ri->stack_pos_is_object.contains(offset))
27666 {
27667 assert(false);
27668 break;
27669 }
27670
27671 1578099 uint32_t id = SH::read_stack(offset);
27672 1578099 script_object_ref_inc(id);
27673 1578099 break;
27674 }
27675 case REF_DEC:
27676 {
27677 int offset = GET_D(rSFRAME) + sarg1;
27678 if (!ri->stack_pos_is_object.contains(offset))
27679 {
27680 assert(false);
27681 break;
27682 }
27683
27684 uint32_t id = SH::read_stack(offset);
27685 script_object_ref_dec(id);
27686 break;
27687 }
27688 case REF_AUTORELEASE:
27689 {
27690 3237076 uint32_t id = get_register(sarg1);
27691
4/4
✓ Branch 0 taken 2211089 times.
✓ Branch 1 taken 1025987 times.
✓ Branch 2 taken 15559 times.
✓ Branch 3 taken 2195530 times.
3237076 if (id && !util::contains(script_object_autorelease_pool, id))
27692 {
27693 2195530 script_object_autorelease_pool.push_back(id);
27694
2/2
✓ Branch 0 taken 17924 times.
✓ Branch 1 taken 2177606 times.
2195530 if (auto object = get_script_object_checked(id))
27695 2177606 object->ref_count++;
27696 2195530 }
27697 3237076 break;
27698 }
27699 case REF_COUNT:
27700 {
27701
1/2
✓ Branch 0 taken 1374 times.
✗ Branch 1 not taken.
1374 if (!use_testingst_start)
27702 {
27703 scripting_log_error_with_context("This function can only be used in test mode");
27704 break;
27705 }
27706
27707 1374 uint32_t id = get_register(sarg1);
27708 1374 auto object = get_script_object(id);
27709
2/2
✓ Branch 0 taken 1359 times.
✓ Branch 1 taken 15 times.
1374 int count = object ? object->ref_count : -1;
27710 1374 set_register(sarg1, count);
27711 1374 break;
27712 }
27713 case MARK_TYPE_STACK:
27714 {
27715 1578099 int offset = GET_D(rSFRAME) + sarg2;
27716
1/2
✓ Branch 0 taken 1578099 times.
✗ Branch 1 not taken.
1578099 if (offset < 0 || offset >= MAX_STACK_SIZE)
27717 {
27718 assert(false);
27719 break;
27720 }
27721
1/2
✓ Branch 0 taken 1578099 times.
✗ Branch 1 not taken.
1578099 if (sarg1 < 0 || sarg1 > 1)
27722 {
27723 assert(false);
27724 break;
27725 }
27726
27727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1578099 times.
1578099 if (sarg1)
27728 1578099 ri->stack_pos_is_object.insert(offset);
27729 else
27730 ri->stack_pos_is_object.erase(offset);
27731 1578099 break;
27732 }
27733 case MARK_TYPE_REG:
27734 {
27735 2998 markRegisterType(sarg1, sarg2);
27736 2998 break;
27737 }
27738 case REF_REMOVE:
27739 {
27740 int offset = GET_D(rSFRAME) + sarg1;
27741 script_remove_object_ref(offset);
27742 break;
27743 }
27744 case GC:
27745 {
27746
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 226 times.
226 if (!use_testingst_start)
27747 {
27748 Z_error_fatal("GC can only be used in test mode\n");
27749 break;
27750 }
27751
27752 226 run_gc();
27753 226 break;
27754 }
27755 case SET_OBJECT:
27756 {
27757
1/2
✓ Branch 0 taken 2427 times.
✗ Branch 1 not taken.
2427 if (!(sarg1 >= GD(0) && sarg1 <= GD(MAX_SCRIPT_REGISTERS)))
27758 {
27759 assert(false);
27760 break;
27761 }
27762
27763 2427 int value = get_register(sarg2);
27764 2427 int index = sarg1-GD(0);
27765
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2427 times.
2427 assert(game->global_d_types[index] != script_object_type::none);
27766 2427 script_object_ref_inc(value);
27767 2427 script_object_ref_dec(game->global_d[index]);
27768 2427 game->global_d[index] = value;
27769 2427 break;
27770 }
27771 case LOAD_INTERNAL_ARRAY:
27772 {
27773 4 do_load_internal_array();
27774 4 break;
27775 }
27776 case LOAD_INTERNAL_ARRAY_REF:
27777 {
27778 22 do_load_internal_array_ref();
27779 22 break;
27780 }
27781
27782 default:
27783 {
27784
1/2
✓ Branch 0 taken 6689206 times.
✗ Branch 1 not taken.
6689206 if (auto r = scripting_engine_run_command(scommand))
27785 {
27786
2/2
✓ Branch 0 taken 6689200 times.
✓ Branch 1 taken 6 times.
6689206 if (*r != RUNSCRIPT_OK)
27787 6 return *r;
27788 6689200 break;
27789 }
27790
27791 scripting_log_error_with_context("Invalid ZASM command {} reached; terminating", scommand);
27792 hit_invalid_zasm = true;
27793 scommand = 0xFFFF;
27794 #ifdef _DEBUG
27795 Z_error_fatal("Invalid ZASM command: %d\n", scommand);
27796 #endif
27797 break;
27798 }
27799 }
27800
1/2
✓ Branch 0 taken 1532348602 times.
✗ Branch 1 not taken.
1532348602 if(earlyretval == RUNSCRIPT_SELFDELETE)
27801 {
27802 earlyretval = -1;
27803 return RUNSCRIPT_SELFDELETE;
27804 }
27805
1/2
✓ Branch 0 taken 1532348602 times.
✗ Branch 1 not taken.
1532348602 if (ri->overflow)
27806 {
27807 if (old_script_funcrun)
27808 return RUNSCRIPT_OK;
27809 scommand = 0xFFFF;
27810 }
27811
1/2
✓ Branch 0 taken 1532348602 times.
✗ Branch 1 not taken.
1532348602 if(hit_invalid_zasm) break;
27812
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1532348602 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1532348602 if(old_script_funcrun && (ri->pc == MAX_PC || scommand == RETURN))
27813 return RUNSCRIPT_OK;
27814
27815
2/2
✓ Branch 0 taken 1528625024 times.
✓ Branch 1 taken 3723578 times.
1532348602 if (type == ScriptType::Combo)
27816 {
27817
1/2
✓ Branch 0 taken 3723578 times.
✗ Branch 1 not taken.
3723578 if(combopos_modified == i)
27818 {
27819 //Combo changed! Abort script!
27820 return RUNSCRIPT_OK;
27821 }
27822 3723578 }
27823
2/2
✓ Branch 0 taken 93156 times.
✓ Branch 1 taken 1532255446 times.
1532348602 if(scommand != 0xFFFF)
27824 {
27825
2/2
✓ Branch 0 taken 1522207121 times.
✓ Branch 1 taken 10048325 times.
1532255446 if(increment) ri->pc++;
27826 10048325 else increment = true;
27827
1/2
✓ Branch 0 taken 1532255446 times.
✗ Branch 1 not taken.
1532255446 if ( ri->pc == MAX_PC ) //rolled over from overflow?
27828 {
27829 Z_scripterrlog("Script PC overflow! Too many ZASM lines?\n");
27830 ri->pc = curscript->pc;
27831 scommand = 0xFFFF;
27832 }
27833 1532255446 }
27834
27835
1/2
✓ Branch 0 taken 1532348602 times.
✗ Branch 1 not taken.
1532348602 if(earlyretval > -1) //Should this be below the 'commands_run += 1'? Unsure. -Em
27836 {
27837 auto v = earlyretval;
27838 earlyretval = -1;
27839 return earlyretval;
27840 }
27841
27842 // If running a JIT compiled script, we're only here to do a few commands.
27843 1532348602 commands_run += 1;
27844
4/4
✓ Branch 0 taken 1492926203 times.
✓ Branch 1 taken 39422399 times.
✓ Branch 2 taken 156704162 times.
✓ Branch 3 taken 1336222041 times.
1532348602 if (is_jitted && commands_run == j_instance->uncompiled_command_count)
27845 {
27846 1336222041 current_zasm_command=(ASM_DEFINE)0;
27847 1336222041 break;
27848 }
27849 }
27850
2/2
✓ Branch 0 taken 810 times.
✓ Branch 1 taken 1370779948 times.
1370780758 if(script_funcrun) return RUNSCRIPT_OK;
27851
27852
2/2
✓ Branch 0 taken 1370779918 times.
✓ Branch 1 taken 30 times.
1370779948 if(!scriptCanSave)
27853 30 scriptCanSave=true;
27854
27855
2/2
✓ Branch 0 taken 1364125914 times.
✓ Branch 1 taken 6654034 times.
1370779948 if(scommand == WAITDRAW)
27856 {
27857
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 6637752 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 16282 times.
6654034 switch(type)
27858 {
27859 case ScriptType::Global:
27860 case ScriptType::Hero:
27861 case ScriptType::DMap:
27862 case ScriptType::OnMap:
27863 case ScriptType::ScriptedPassiveSubscreen:
27864 case ScriptType::ScriptedActiveSubscreen:
27865 case ScriptType::Screen:
27866 case ScriptType::Combo:
27867 case ScriptType::NPC:
27868 case ScriptType::Lwpn:
27869 case ScriptType::Ewpn:
27870 case ScriptType::ItemSprite:
27871 6637752 FFCore.waitdraw(type, i) = true;
27872 6637752 break;
27873
27874 case ScriptType::Item:
27875 {
27876 if (!get_qr(qr_NOITEMWAITDRAW))
27877 {
27878 FFCore.waitdraw(ScriptType::Item, i) = true;
27879 }
27880 break;
27881 }
27882
27883 case ScriptType::FFC:
27884 {
27885
2/2
✓ Branch 0 taken 1221 times.
✓ Branch 1 taken 15061 times.
16282 if ( !(get_qr(qr_NOFFCWAITDRAW)) )
27886 {
27887 15061 FFCore.waitdraw(ScriptType::FFC, i) = true;
27888 15061 }
27889 else
27890 {
27891 1221 Z_scripterrlog("Waitdraw cannot be used in script type: %s\n", "ffc, with Script Rule 'No FFC Waitdraw() enabled!");
27892 }
27893 16282 break;
27894 }
27895
27896 case ScriptType::Generic:
27897 case ScriptType::GenericFrozen:
27898 case ScriptType::EngineSubscreen:
27899 //No Waitdraw
27900 break;
27901
27902 default:
27903 Z_scripterrlog("Waitdraw cannot be used in script type: %s\n", ScriptTypeToString(type));
27904 break;
27905 }
27906 6654034 }
27907
27908
2/2
✓ Branch 0 taken 92346 times.
✓ Branch 1 taken 1370687602 times.
1370779948 if(scommand == 0xFFFF) //Quit/command list end reached/bad command
27909 {
27910 92346 script_exit_cleanup(no_dealloc);
27911 92346 return RUNSCRIPT_STOPPED;
27912 }
27913
27914
4/4
✓ Branch 0 taken 1370686316 times.
✓ Branch 1 taken 1286 times.
✓ Branch 2 taken 34555986 times.
✓ Branch 3 taken 1336130330 times.
1370687602 if (is_jitted && commands_run == j_instance->uncompiled_command_count)
27915 1336130330 return RUNSCRIPT_OK;
27916
27917 34557272 ri->pc++;
27918
27919 34557272 return RUNSCRIPT_OK;
27920 1370784711 }
27921
27922 6386 script_data* load_scrdata(ScriptType type, word script, int32_t i)
27923 {
27924
2/15
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 4766 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1620 times.
✗ Branch 14 not taken.
6386 switch(type)
27925 {
27926 case ScriptType::FFC:
27927 return ffscripts[script];
27928 case ScriptType::NPC:
27929 return guyscripts[guys.getByUID(i)->script];
27930 case ScriptType::Lwpn:
27931 return lwpnscripts[Lwpns.getByUID(i)->script];
27932 case ScriptType::Ewpn:
27933 return ewpnscripts[Ewpns.getByUID(i)->script];
27934 case ScriptType::ItemSprite:
27935 return itemspritescripts[items.getByUID(i)->script];
27936 case ScriptType::Item:
27937 return itemscripts[script];
27938 case ScriptType::Global:
27939 return globalscripts[script];
27940 case ScriptType::Generic:
27941 case ScriptType::GenericFrozen:
27942 1620 return genericscripts[script];
27943 case ScriptType::Hero:
27944 return playerscripts[script];
27945 case ScriptType::DMap:
27946 return dmapscripts[script];
27947 case ScriptType::OnMap:
27948 case ScriptType::ScriptedActiveSubscreen:
27949 case ScriptType::ScriptedPassiveSubscreen:
27950 return dmapscripts[script];
27951 case ScriptType::Screen:
27952 return screenscripts[script];
27953 case ScriptType::Combo:
27954 return comboscripts[script];
27955 case ScriptType::EngineSubscreen:
27956 return subscreenscripts[script];
27957 }
27958 4766 return nullptr;
27959 6386 }
27960
27961 //This keeps ffc scripts running beyond the first frame.
27962 14966551 int32_t ffscript_engine(const bool preload)
27963 {
27964
2/2
✓ Branch 0 taken 14930055 times.
✓ Branch 1 taken 36496 times.
14966551 if(preload)
27965 {
27966 36496 throwGenScriptEvent(GENSCR_EVENT_FFC_PRELOAD);
27967 36496 handle_region_load_trigger();
27968 36496 }
27969
27970
6/6
✓ Branch 0 taken 14963965 times.
✓ Branch 1 taken 2586 times.
✓ Branch 2 taken 2364860 times.
✓ Branch 3 taken 12599105 times.
✓ Branch 4 taken 2350783 times.
✓ Branch 5 taken 14077 times.
14966551 if (!FFCore.system_suspend[susptSCREENSCRIPTS] && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && !get_qr(qr_ZS_OLD_SUSPEND_FFC))
27971 {
27972 28154 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
27973
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 14058 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 14039 times.
14077 if ((preload && scr->preloadscript) || !preload)
27974 {
27975
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14058 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14058 if (scr->script > 0 && FFCore.doscript(ScriptType::Screen, scr->screen))
27976 {
27977 ZScriptVersion::RunScript(ScriptType::Screen, scr->script, scr->screen);
27978 }
27979 14058 }
27980 14077 });
27981 14077 }
27982
27983
2/2
✓ Branch 0 taken 2586 times.
✓ Branch 1 taken 14963965 times.
14966551 if (!FFCore.system_suspend[susptFFCSCRIPTS])
27984 {
27985 //intentional it's for compatability
27986
4/4
✓ Branch 0 taken 2364860 times.
✓ Branch 1 taken 12599105 times.
✓ Branch 2 taken 14077 times.
✓ Branch 3 taken 2350783 times.
14963965 if (FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && get_qr(qr_ZS_OLD_SUSPEND_FFC))
27987 {
27988 5090642 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
27989
4/4
✓ Branch 0 taken 6822 times.
✓ Branch 1 taken 2733037 times.
✓ Branch 2 taken 6743 times.
✓ Branch 3 taken 2726294 times.
2739859 if ((preload && scr->preloadscript) || !preload)
27990 {
27991
3/4
✓ Branch 0 taken 50461 times.
✓ Branch 1 taken 2682655 times.
✓ Branch 2 taken 50461 times.
✗ Branch 3 not taken.
2733116 if (scr->script > 0 && FFCore.doscript(ScriptType::Screen, scr->screen))
27992 {
27993 50461 ZScriptVersion::RunScript(ScriptType::Screen, scr->script, scr->screen);
27994 50461 }
27995 2733116 }
27996 2739859 });
27997 2350783 }
27998
27999 459439440 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
28000
2/2
✓ Branch 0 taken 11826077 times.
✓ Branch 1 taken 432649398 times.
444475475 if(ffc_handle.ffc->script == 0)
28001 432649398 return;
28002
28003
4/4
✓ Branch 0 taken 14710 times.
✓ Branch 1 taken 11811367 times.
✓ Branch 2 taken 11170 times.
✓ Branch 3 taken 3540 times.
11826077 if(preload && !(ffc_handle.ffc->flags&ffc_preload))
28004 11170 return;
28005
28006
4/4
✓ Branch 0 taken 11810348 times.
✓ Branch 1 taken 4559 times.
✓ Branch 2 taken 11715274 times.
✓ Branch 3 taken 95074 times.
11814907 if((ffc_handle.ffc->flags&ffc_ignoreholdup)==0 && Hero.getHoldClk()>0)
28007 95074 return;
28008
28009 11719833 ZScriptVersion::RunScript(ScriptType::FFC, ffc_handle.ffc->script, ffc_handle.id);
28010 444475475 });
28011 14963965 }
28012
28013
28014 14966551 return 0;
28015 }
28016
28017
28018
28019 ///----------------------------------------------------------------------------------------------------
28020
28021 435 void FFScript::user_files_init()
28022 {
28023 435 files_init();
28024 435 }
28025
28026 435 void FFScript::user_dirs_init()
28027 {
28028 435 dirs_init();
28029 435 }
28030 435 void FFScript::user_objects_init()
28031 {
28032 435 ::user_object_init();
28033 435 }
28034
28035 435 void FFScript::user_stacks_init()
28036 {
28037 435 user_stacks.clear();
28038 435 }
28039
28040 1149 void FFScript::user_rng_init()
28041 {
28042 1149 user_rngs.clear();
28043
2/2
✓ Branch 0 taken 294144 times.
✓ Branch 1 taken 1149 times.
295293 for(int32_t q = 0; q < MAX_USER_RNGS; ++q)
28044 {
28045 294144 replay_register_rng(&script_rnggens[q]);
28046
28047 // Just to seed it.
28048 294144 user_rng rng;
28049 294144 rng.set_gen(&script_rnggens[q]);
28050 294144 }
28051 1149 }
28052
28053 435 void FFScript::user_paldata_init()
28054 {
28055 435 user_paldatas.clear();
28056 435 }
28057
28058 435 void FFScript::user_websockets_init()
28059 {
28060 435 websocket_init();
28061 435 }
28062
28063 637 void FFScript::script_arrays_init()
28064 {
28065 637 script_arrays.clear();
28066 637 }
28067
28068 ///----------------------------------------------------------------------------------------------------
28069
28070 8420 void FFScript::do_isvalidbitmap()
28071 {
28072 8420 int32_t id = get_register(sarg1);
28073
28074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8420 times.
8420 if (id >= 0)
28075 {
28076 8420 auto bmp = user_bitmaps.check(id, true);
28077
3/4
✓ Branch 0 taken 8370 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 8370 times.
✗ Branch 3 not taken.
8420 if (bmp && bmp->u_bmp)
28078 {
28079 8370 set_register(sarg1, 10000);
28080 8370 return;
28081 }
28082 50 }
28083
28084 50 set_register(sarg1, 0);
28085 8420 }
28086 117 void FFScript::do_isallocatedbitmap()
28087 {
28088 117 int32_t id = get_register(sarg1);
28089
28090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 if (id >= 0)
28091 {
28092 117 auto bmp = user_bitmaps.check(id, true);
28093
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 115 times.
117 if (bmp)
28094 {
28095 115 set_register(sarg1, 10000);
28096 115 return;
28097 }
28098 2 }
28099
28100 2 set_register(sarg1, 0);
28101 117 }
28102
28103 435 void FFScript::user_bitmaps_init()
28104 {
28105 435 user_bitmaps.clear();
28106 435 }
28107
28108 1509495 int32_t FFScript::do_create_bitmap()
28109 {
28110 1509495 int32_t w = (GET_D(rINDEX2) / 10000);
28111 1509495 int32_t h = (GET_D(rINDEX)/10000);
28112
1/2
✓ Branch 0 taken 1509495 times.
✗ Branch 1 not taken.
1509495 if ( get_qr(qr_OLDCREATEBITMAP_ARGS) )
28113 {
28114 std::swap(w, h);
28115 }
28116
28117 1509495 return create_user_bitmap_ex(h,w);
28118 }
28119
28120 1509495 uint32_t FFScript::create_user_bitmap_ex(int32_t w, int32_t h)
28121 {
28122 1509495 auto bmp = user_bitmaps.create();
28123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1509495 times.
1509495 if (!bmp)
28124 return 0;
28125
28126 1509495 bmp->width = w;
28127 1509495 bmp->height = h;
28128 1509495 bmp->u_bmp = create_bitmap_ex(8,w,h);
28129 1509495 clear_bitmap(bmp->u_bmp);
28130 1509495 return bmp->id;
28131 1509495 }
28132
28133 21102680 bool FFScript::doesResolveToScreenBitmap(int32_t bitmap_id)
28134 {
28135
2/2
✓ Branch 0 taken 11414644 times.
✓ Branch 1 taken 9688036 times.
21102680 if (bitmap_id == rtSCREEN)
28136 9688036 return true;
28137
28138
2/2
✓ Branch 0 taken 12946 times.
✓ Branch 1 taken 11401698 times.
11414644 if (bitmap_id == -2)
28139 {
28140 12946 int curr_rt = zscriptDrawingRenderTarget->GetCurrentRenderTarget();
28141
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12946 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12946 if (curr_rt >= 0 && curr_rt < 7)
28142 return false;
28143
28144 12946 return true;
28145 }
28146
28147 11401698 return false;
28148 21102680 }
28149
28150 21102680 bool FFScript::doesResolveToDeprecatedSystemBitmap(int32_t bitmap_id)
28151 {
28152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21102680 times.
21102680 switch (bitmap_id)
28153 {
28154 case rtBMP0:
28155 case rtBMP1:
28156 case rtBMP2:
28157 case rtBMP3:
28158 case rtBMP4:
28159 case rtBMP5:
28160 case rtBMP6:
28161 {
28162 return true;
28163 }
28164 }
28165
28166
2/2
✓ Branch 0 taken 21089734 times.
✓ Branch 1 taken 12946 times.
21102680 if (bitmap_id == -2)
28167 {
28168 12946 int curr_rt = zscriptDrawingRenderTarget->GetCurrentRenderTarget();
28169
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12946 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12946 if (curr_rt >= 0 && curr_rt < 7)
28170 return true;
28171 12946 }
28172
28173 21102680 return false;
28174 21102680 }
28175
28176 66997310 BITMAP* FFScript::GetScriptBitmap(int32_t id, BITMAP* screen_bmp, bool skipError)
28177 {
28178
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 66996830 times.
✓ Branch 2 taken 480 times.
66997310 switch (id - 10)
28179 {
28180 case rtSCREEN:
28181 480 return screen_bmp;
28182
28183 case rtBMP0:
28184 case rtBMP1:
28185 case rtBMP2:
28186 case rtBMP3:
28187 case rtBMP4:
28188 case rtBMP5:
28189 case rtBMP6: //old system bitmaps (render targets)
28190 {
28191 return zscriptDrawingRenderTarget->GetBitmapPtr(id - 10);
28192 }
28193 }
28194
28195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66996830 times.
66996830 if (auto bitmap = checkBitmap(id, true, skipError))
28196 66996830 return bitmap->u_bmp;
28197
28198 return nullptr;
28199 66997310 }
28200
28201 450 uint32_t FFScript::get_free_bitmap(bool skipError)
28202 {
28203 450 auto bmp = user_bitmaps.create(skipError);
28204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 450 times.
450 if (!bmp)
28205 return 0;
28206 450 return bmp->id;
28207 450 }
28208
28209 3512 void FFScript::do_deallocate_bitmap()
28210 {
28211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3512 times.
3512 if (ZScriptVersion::gc())
28212 return;
28213
28214
1/2
✓ Branch 0 taken 3512 times.
✗ Branch 1 not taken.
3512 if(isSystemBitref(GET_REF(bitmapref)))
28215 {
28216 return; //Don't attempt to deallocate system bitmaps!
28217 }
28218
28219 // Bitmaps are not deallocated right away, but deferred until the next call to scb.update()
28220
1/2
✓ Branch 0 taken 3512 times.
✗ Branch 1 not taken.
3512 if (auto b = checkBitmap(GET_REF(bitmapref), false, true))
28221 3512 b->free_obj();
28222 3512 }
28223
28224 3658 bool FFScript::isSystemBitref(int32_t ref)
28225 {
28226
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 switch(ref-10)
28227 {
28228 case rtSCREEN:
28229 case rtBMP0:
28230 case rtBMP1:
28231 case rtBMP2:
28232 case rtBMP3:
28233 case rtBMP4:
28234 case rtBMP5:
28235 case rtBMP6:
28236 return true;
28237 }
28238 3658 return false;
28239 3658 }
28240
28241 ///----------------------------------------------------------------------------------------------------
28242
28243 2197 int32_t FFScript::GetQuestVersion()
28244 {
28245 2197 return QHeader.zelda_version;
28246 }
28247 729 int32_t FFScript::GetQuestBuild()
28248 {
28249 729 return QHeader.build;
28250 }
28251 int32_t FFScript::GetQuestSectionVersion(int32_t section)
28252 {
28253 return QHeader.zelda_version;
28254 }
28255
28256 19 int32_t FFScript::GetDefaultWeaponSprite(int32_t wpn_id)
28257 {
28258
2/63
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✓ Branch 49 taken 10 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
19 switch (wpn_id)
28259 {
28260 case wNone:
28261 return 0;
28262
28263 case wSword: return 0;
28264 case wBeam: return 1;
28265 case wBrang: return 4;
28266 case wBomb: return 9;
28267 case wSBomb: return 75;
28268 case wLitBomb: return 7;
28269 case wLitSBomb: return 8;
28270 case wArrow: return 10;
28271 case wRefArrow: return 10;
28272 case wFire: return 12;
28273 case wRefFire: return 12;
28274 case wRefFire2: return 12;
28275 case wWhistle: return 45; //blank, unused misc sprite
28276 case wBait: return 14;
28277 case wWand: return 15;
28278 case wMagic: return 16;
28279 case wCatching: return 45; //blank, unused misc sprite
28280 case wWind: return 13;
28281 case wRefMagic: return 16;
28282 case wRefFireball: return 17;
28283 case wRefRock: return 18;
28284 case wHammer: return 25;
28285 case wHookshot: return 26;
28286 case wHSHandle: return 28;
28287 case wHSChain: return 27;
28288 case wSSparkle: return 29;
28289 case wFSparkle: return 32;
28290 case wSmack: return 33;
28291 case wPhantom: return -1;
28292 case wCByrna: return 87;
28293 case wRefBeam: return 1;
28294 case wStomp: return 45; //blank, unused misc sprite
28295 case lwMax: return 45; //blank, unused misc sprite
28296 case wScript1: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 246; else return 0; }
28297 case wScript2: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 247; else return 0; }
28298 case wScript3: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 248; else return 0; }
28299 case wScript4: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 249; else return 0; }
28300 case wScript5: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 250; else return 0; }
28301 case wScript6: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 251; else return 0; }
28302 case wScript7: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 252; else return 0; }
28303 case wScript8: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 253; else return 0; }
28304 case wScript9: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 254; else return 0; }
28305 case wScript10: { if ( get_qr(qr_WRITING_NPC_WEAPON_UNIQUE_SPRITES ) ) return 255; else return 0; }
28306
28307 case wIce: return 83;
28308 //Cannot use any of these weapons yet.
28309 //return -1;
28310
28311 case wEnemyWeapons:
28312 9 case ewFireball: return 17;
28313
28314 case ewArrow: return 19;
28315 case ewBrang: return 4;
28316 10 case ewSword: return 20;
28317 case ewRock: return 18;
28318 case ewMagic: return 21;
28319 case ewBomb: return 78;
28320 case ewSBomb: return 79;
28321 case ewLitBomb: return 76;
28322 case ewLitSBomb: return 77;
28323 case ewFireTrail: return 80;
28324 case ewFlame: return 35;
28325 case ewWind: return 36;
28326 case ewFlame2: return 81;
28327 case ewFlame2Trail: return 82;
28328 case ewIce: return 83;
28329 case ewFireball2: return 17; //fireball (rising)
28330
28331
28332 default: return -1; //No assign.
28333
28334 }
28335 19 }
28336
28337 19 int32_t FFScript::GetDefaultWeaponSFX(int32_t wpn_id)
28338 {
28339
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
19 switch (wpn_id)
28340 {
28341 case ewFireTrail:
28342 case ewFlame:
28343 case ewFlame2Trail:
28344 case ewFlame2:
28345 return WAV_FIRE; break;
28346 case ewWind:
28347 case ewMagic:
28348 return WAV_WAND; break;
28349 case ewIce:
28350 return WAV_ZN1ICE; break;
28351 case ewRock:
28352 return WAV_ZN1ROCK; break;
28353 case ewFireball2:
28354 case ewFireball:
28355 9 return WAV_ZN1FIREBALL; break;
28356 }
28357 10 return -1; //no assign
28358 19 }
28359
28360 void FFScript::do_bmpcollision()
28361 {
28362 int32_t bmpref = SH::read_stack(ri->sp + 5);
28363 int32_t maskbmpref = SH::read_stack(ri->sp + 4);
28364 int32_t x = SH::read_stack(ri->sp + 3) / 10000;
28365 int32_t y = SH::read_stack(ri->sp + 2) / 10000;
28366 int32_t checkCol = SH::read_stack(ri->sp + 1) / 10000;
28367 int32_t maskCol = SH::read_stack(ri->sp + 0) / 10000;
28368 BITMAP *checkbit = FFCore.GetScriptBitmap(bmpref, screen, true);
28369 BITMAP *maskbit = FFCore.GetScriptBitmap(maskbmpref, screen, true);
28370 if(!(checkbit && maskbit))
28371 {
28372 set_register(sarg1, -10000);
28373 char buf1[16];
28374 char buf2[16];
28375 zc_itoa(bmpref, buf1);
28376 zc_itoa(maskbmpref, buf2);
28377 Z_scripterrlog("Invalid bitmap%s passed to 'bitmap->CountColor()': %s%s%s\n",
28378 (checkbit || maskbit) ? "" : "s", checkbit ? "" : buf1,
28379 (checkbit || maskbit) ? "" : ", ", maskbit ? "" : buf2);
28380 return;
28381 }
28382 int32_t ret = countColor(checkbit, maskbit, x, y, checkCol, maskCol);
28383 set_register(sarg1, ret*10000);
28384 }
28385
28386
28387 7237302 int32_t FFScript::loadMapData()
28388 {
28389 7237302 int32_t map = (GET_D(rINDEX) / 10000);
28390 7237302 int32_t screen = (GET_D(rINDEX2)/10000);
28391
2/2
✓ Branch 0 taken 7237282 times.
✓ Branch 1 taken 20 times.
7237302 int32_t indx = (zc_max((map)-1,0) * MAPSCRS + screen);
28392
3/4
✓ Branch 0 taken 7237282 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7237282 times.
7237302 if ( map < 1 || map > map_count )
28393 {
28394 20 Z_scripterrlog("Invalid Map ID passed to Game->LoadMapData: %d\n", map);
28395 20 ri->mapdataref = MAX_SIGNED_32;
28396 20 }
28397
2/4
✓ Branch 0 taken 7237282 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7237282 times.
7237282 else if ( screen < 0 || screen > 129 ) //0x00 to 0x81 -Z
28398 {
28399 Z_scripterrlog("Invalid Screen Index passed to Game->LoadMapData: %d\n", screen);
28400 ri->mapdataref = MAX_SIGNED_32;
28401 }
28402 7237282 else ri->mapdataref = indx;
28403 7237302 return ri->mapdataref;
28404 }
28405
28406 // Called when leaving a screen; deallocate arrays created by FFCs that aren't carried over
28407 13697902 void FFScript::deallocateArray(int32_t ptrval)
28408 {
28409
1/2
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
13697902 CHECK(!ZScriptVersion::gc_arrays());
28410
28411
1/2
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
13697902 if(ptrval == 0)
28412 return;
28413
2/4
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13697902 times.
13697902 if(ptrval==0 || ptrval >= NUM_ZSCRIPT_ARRAYS)
28414 scripting_log_error_with_context("Script tried to deallocate memory at invalid address {}", ptrval);
28415
1/2
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
13697902 else if(ptrval<0)
28416 scripting_log_error_with_context("Script tried to deallocate memory at object-based address {}", ptrval);
28417 else
28418 {
28419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13697902 times.
13697902 if(arrayOwner[ptrval].specOwned) return; //ignore this deallocation
28420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13697902 times.
13697902 if(arrayOwner[ptrval].specCleared) return;
28421 13697902 arrayOwner[ptrval].clear();
28422
28423
1/2
✓ Branch 0 taken 13697902 times.
✗ Branch 1 not taken.
13697902 if(!localRAM[ptrval].Valid())
28424 scripting_log_error_with_context("Script tried to deallocate memory that was not allocated at address {}", ptrval);
28425 else
28426 {
28427
2/2
✓ Branch 0 taken 13697899 times.
✓ Branch 1 taken 3 times.
13697902 if (localRAM[ptrval].HoldsObjects())
28428 {
28429 3 auto&& aptr = localRAM[ptrval];
28430
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 for (int i = 0; i < aptr.Size(); i++)
28431 {
28432 2 int id = aptr[i];
28433 2 script_object_ref_dec(id);
28434 2 }
28435 3 }
28436 13697902 localRAM[ptrval].Clear();
28437 }
28438 }
28439 13697902 }
28440
28441 2681734 int32_t FFScript::get_screen_d(int32_t index1, int32_t index2)
28442 {
28443
3/4
✓ Branch 0 taken 2681734 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2681728 times.
2681734 if(index2 < 0 || index2 > 7)
28444 {
28445 6 scripting_log_error_with_context("You were trying to reference an out-of-bounds array index for a screen's D[] array ({}); valid indices are from 0 to 7.", index1);
28446 6 return 0;
28447 }
28448
2/4
✓ Branch 0 taken 2681728 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2681728 times.
2681728 if (index1 < 0 || index1 >= game->screen_d.size())
28449 {
28450 scripting_log_error_with_context("You were trying to reference an out-of-bounds screen for a D[] array ({}); valid indices are from 0 to %u.", index1, game->screen_d.size() - 1);
28451 return 0;
28452 }
28453
28454 2681728 return game->screen_d[index1][index2];
28455 2681734 }
28456
28457 54512 void FFScript::set_screen_d(int32_t index1, int32_t index2, int32_t val)
28458 {
28459
2/4
✓ Branch 0 taken 54512 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54512 times.
54512 if(index2 < 0 || index2 > 7)
28460 {
28461 scripting_log_error_with_context("You were trying to reference an out-of-bounds array index for a screen's D[] array ({}); valid indices are from 0 to 7.", index1);
28462 return;
28463 }
28464
2/4
✓ Branch 0 taken 54512 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 54512 times.
54512 if (index1 < 0 || index1 >= game->screen_d.size())
28465 {
28466 scripting_log_error_with_context("You were trying to reference an out-of-bounds screen for a D[] array ({}); valid indices are from 0 to %u.", index1, game->screen_d.size() - 1);
28467 return;
28468 }
28469
28470 54512 game->screen_d[index1][index2] = val;
28471 54512 }
28472
28473 void FFScript::do_zapout()
28474 {
28475 zapout();
28476 }
28477
28478 void FFScript::do_zapin(){ zapin(); }
28479
28480 void FFScript::do_openscreen() { openscreen(); }
28481 void FFScript::do_closescreen() { closescreen(); }
28482 void FFScript::do_openscreenshape()
28483 {
28484 int32_t shape = get_register(sarg1) / 10000;
28485 if(shape < 0 || shape >= bosMAX)
28486 {
28487 Z_scripterrlog("Invalid shape passed to %s! Valid range %d to %d. Using 'Circle' shape.\n", "Screen->OpeningWipe(int32_t)", 0, bosMAX-1);
28488 shape = bosCIRCLE;
28489 }
28490 openscreen(shape);
28491 }
28492 void FFScript::do_closescreenshape()
28493 {
28494 int32_t shape = get_register(sarg1) / 10000;
28495 if(shape < 0 || shape >= bosMAX)
28496 {
28497 Z_scripterrlog("Invalid shape passed to %s! Valid range %d to %d. Using 'Circle' shape.\n", "Screen->ClosingWipe(int32_t)", 0, bosMAX-1);
28498 shape = bosCIRCLE;
28499 }
28500 closescreen(shape);
28501 }
28502 void FFScript::do_wavyin() { wavyin(); }
28503 void FFScript::do_wavyout() { wavyout(false); }
28504
28505
28506 void FFScript::do_triggersecret(const bool v)
28507 {
28508 int32_t ID = vbound((SH::get_arg(sarg1, v) / 10000), 0, 255);
28509 mapscr *s = hero_scr;
28510 //Convert a flag type to a secret type.
28511 int32_t ft = combo_trigger_flag_to_secret_combo_index(ID);
28512 if (ft != -1)
28513 {
28514 for(int32_t iter=0; iter<2; ++iter)
28515 {
28516 for ( int32_t q = 0; q < 176; q++ )
28517 {
28518 //Placed flags
28519 if ( iter == 1 )
28520 {
28521 if ( s->sflag[q] == ID ) {
28522 auto rpos_handle = get_rpos_handle_for_screen(s->screen, 0, q);
28523 screen_combo_modify_preroutine(rpos_handle);
28524 s->data[q] = s->secretcombo[ft];
28525 s->cset[q] = s->secretcset[ft];
28526 s->sflag[q] = s->secretflag[ft];
28527 screen_combo_modify_postroutine(rpos_handle);
28528 }
28529 }
28530 //Inherent flags
28531 else
28532 {
28533 if ( combobuf[s->data[q]].flag == ID ) {
28534 auto rpos_handle = get_rpos_handle_for_screen(s->screen, 0, q);
28535 screen_combo_modify_preroutine(rpos_handle);
28536 s->data[q] = s->secretcombo[ft];
28537 s->cset[q] = s->secretcset[ft];
28538 screen_combo_modify_postroutine(rpos_handle);
28539 }
28540
28541 }
28542 }
28543 }
28544 }
28545
28546 }
28547
28548 2004 void FFScript::do_setMIDI_volume(int32_t m)
28549 {
28550 2004 master_volume(-1,(vbound(m,0,255)));
28551 2004 }
28552 2004 void FFScript::do_setMusic_volume(int32_t m)
28553 {
28554 2004 emusic_volume = vbound(m,0,255);
28555 2004 }
28556 2004 void FFScript::do_setDIGI_volume(int32_t m)
28557 {
28558 2004 master_volume((vbound(m,0,255)),-1);
28559 2004 }
28560 void FFScript::do_setSFX_volume(int32_t m)
28561 {
28562 sfx_volume = m;
28563 }
28564 void FFScript::do_setSFX_pan(int32_t m)
28565 {
28566 pan_style = vbound(m,0,3);
28567 }
28568 8 int32_t FFScript::do_getMIDI_volume()
28569 {
28570 8 return ((int32_t)midi_volume);
28571 }
28572 8 int32_t FFScript::do_getMusic_volume()
28573 {
28574 8 return ((int32_t)emusic_volume);
28575 }
28576 8 int32_t FFScript::do_getDIGI_volume()
28577 {
28578 8 return ((int32_t)digi_volume);
28579 }
28580 int32_t FFScript::do_getSFX_volume()
28581 {
28582 return ((int32_t)sfx_volume);
28583 }
28584 int32_t FFScript::do_getSFX_pan()
28585 {
28586 return ((int32_t)pan_style);
28587 }
28588
28589
28590 //Change Game Over Screen Values
28591 void FFScript::FFSetSaveScreenSetting()
28592 {
28593
28594 int32_t indx = get_register(sarg1) / 10000;
28595 int32_t value = get_register(sarg2) / 10000; //bounded in zelda.cpp
28596 if(indx < 0 || indx > 11)
28597 set_register(sarg1, -10000);
28598 else
28599 SetSaveScreenSetting(indx, value);
28600 }
28601
28602
28603
28604 void FFScript::FFChangeSubscreenText()
28605 {
28606
28607 int32_t index = get_register(sarg1) / 10000;
28608 int32_t arrayptr = get_register(sarg2);
28609
28610 if ( index < 0 || index > 3 )
28611 {
28612 al_trace("The index supplied to Game->SetSubscreenText() is invalid. The index specified was: %d /n", index);
28613 return;
28614 }
28615
28616 string filename_str;
28617 ArrayH::getString(arrayptr, filename_str, 73);
28618 ChangeSubscreenText(index,filename_str.c_str());
28619 }
28620
28621 55 void FFScript::SetItemMessagePlayed(int32_t itm)
28622 {
28623 55 game->item_messages_played[itm] = 1;
28624 55 }
28625 81 bool FFScript::GetItemMessagePlayed(int32_t itm)
28626 {
28627 81 return ((game->item_messages_played[itm] ) ? true : false);
28628 }
28629
28630 int32_t FFScript::getQRBit(int32_t rule)
28631 {
28632 return ( get_qr(rule) ? 1 : 0 );
28633 }
28634
28635 27141249 void FFScript::setHeroAction(int32_t a)
28636 {
28637 27141249 FF_hero_action = vbound(a, 0, 255);
28638 27141249 }
28639
28640 112790563 int32_t FFScript::getHeroAction()
28641 {
28642 112790563 int32_t special_action = Hero.getAction2();
28643
2/2
✓ Branch 0 taken 849143 times.
✓ Branch 1 taken 111941420 times.
112790563 if ( special_action != -1 ) return special_action; //spin, dive, charge
28644 111941420 else return FF_hero_action; //everything else
28645 112790563 }
28646
28647 1149 void FFScript::init()
28648 {
28649 1149 apply_qr_rules();
28650 1149 eventData.clear();
28651 1149 countGenScripts();
28652 // Some scripts can run even before ~Init (but only if qr_OLD_INIT_SCRIPT_TIMING is on), so figure out
28653 // the global register types ahead of time.
28654 1149 markGlobalRegisters();
28655
2/2
✓ Branch 0 taken 11490 times.
✓ Branch 1 taken 1149 times.
12639 for ( int32_t q = 0; q < wexLast; q++ ) warpex[q] = 0;
28656 1149 temp_no_stepforward = 0;
28657 1149 nostepforward = 0;
28658 1149 numscriptdraws = 0;
28659 1149 skipscriptdraws = false;
28660 1149 max_ff_rules = qr_MAX;
28661 1149 coreflags = 0;
28662 1149 skip_ending_credits = 0;
28663 1149 music_update_cond = 0;
28664 1149 music_update_flags = 0;
28665 //quest_format : is this properly initialised?
28666
2/2
✓ Branch 0 taken 78132 times.
✓ Branch 1 taken 1149 times.
79281 for ( int32_t q = 0; q < susptLAST; q++ ) { system_suspend[q] = 0; }
28667
28668 1149 usr_midi_volume = midi_volume;
28669 1149 usr_digi_volume = digi_volume;
28670 1149 usr_sfx_volume = sfx_volume;
28671 1149 usr_music_volume = emusic_volume;
28672
28673 1149 usr_panstyle = pan_style;
28674 1149 FF_hero_action = 0;
28675 1149 enemy_removal_point[spriteremovalY1] = -32767;
28676 1149 enemy_removal_point[spriteremovalY2] = 32767;
28677 1149 enemy_removal_point[spriteremovalX1] = -32767;
28678 1149 enemy_removal_point[spriteremovalX2] = 32767;
28679 1149 enemy_removal_point[spriteremovalZ1] = -32767;
28680 1149 enemy_removal_point[spriteremovalZ2] = 32767;
28681
28682
2/2
✓ Branch 0 taken 4596 times.
✓ Branch 1 taken 1149 times.
5745 for ( int32_t q = 0; q < 4; q++ )
28683 {
28684 4596 FF_screenbounds[q] = 0;
28685 4596 FF_screen_dimensions[q] = 0;
28686 4596 FF_subscreen_dimensions[q] = 0;
28687 4596 FF_eweapon_removal_bounds[q] = 0;
28688 4596 FF_lweapon_removal_bounds[q] = 0;
28689 4596 }
28690
2/2
✓ Branch 0 taken 11490 times.
✓ Branch 1 taken 1149 times.
12639 for ( int32_t q = 0; q < FFSCRIPTCLASS_CLOCKS; q++ )
28691 {
28692 11490 FF_clocks[q] = 0;
28693 11490 }
28694
2/2
✓ Branch 0 taken 22980 times.
✓ Branch 1 taken 1149 times.
24129 for ( int32_t q = 0; q < SCRIPT_DRAWING_RULES; q++ )
28695 {
28696 22980 ScriptDrawingRules[q] = 0;
28697 22980 }
28698
2/2
✓ Branch 0 taken 6894 times.
✓ Branch 1 taken 1149 times.
8043 for ( int32_t q = 0; q < NUM_USER_MIDI_OVERRIDES; q++ )
28699 {
28700 6894 FF_UserMidis[q] = 0;
28701 6894 }
28702 1149 subscreen_scroll_speed = 0; //make a define for a default and read quest override! -Z
28703 1149 kb_typing_mode = false;
28704 1149 initIncludePaths();
28705 //clearRunningItemScripts();
28706 1149 ScrollingScreensAll.clear();
28707 1149 memset(ScrollingData, 0, sizeof(int32_t) * SZ_SCROLLDATA);
28708 1149 ScrollingData[SCROLLDATA_DIR] = -1;
28709 1149 user_rng_init();
28710 1149 clear_script_engine_data();
28711 1149 script_debug_handles.clear();
28712 1149 runtime_script_debug_handle = nullptr;
28713 1149 }
28714
28715 323 void FFScript::shutdown()
28716 {
28717 323 scriptEngineDatas.clear();
28718 323 objectRAM.clear();
28719 323 script_objects.clear();
28720 323 }
28721
28722 12 void FFScript::SetFFEngineFlag(int32_t flag, bool state)
28723 {
28724
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if ( state ) { coreflags |= flag; }
28725 else coreflags &= ~flag;
28726 12 }
28727
28728 void FFScript::setSubscreenScrollSpeed(byte n)
28729 {
28730 subscreen_scroll_speed = n;
28731 }
28732
28733 int32_t FFScript::getSubscreenScrollSpeed()
28734 {
28735 return (int32_t)subscreen_scroll_speed;
28736 }
28737
28738 void FFScript::do_greyscale(const bool v)
28739 {
28740 // This has been removed.
28741 }
28742
28743 void FFScript::do_monochromatic(const bool v)
28744 {
28745 // This has been removed.
28746 }
28747
28748 10680 static int convert_6bit_to_8bit_color_shift_arg(int v)
28749 {
28750 10680 int va = abs(v);
28751
2/2
✓ Branch 0 taken 10677 times.
✓ Branch 1 taken 3 times.
10680 if (va < 64)
28752 10677 return _rgb_scale_6[va] * sign(v);
28753
28754 3 int vdiv = va / 63;
28755 3 int vmod = va % 63;
28756 3 return (vdiv * 255 + _rgb_scale_6[vmod]) * sign(v);
28757 10680 }
28758
28759 void FFScript::gfxmonohue()
28760 {
28761 int32_t r = SH::read_stack(ri->sp + 3) / 10000;
28762 int32_t g = SH::read_stack(ri->sp + 2) / 10000;
28763 int32_t b = SH::read_stack(ri->sp + 1) / 10000;
28764 if (!scripting_use_8bit_colors)
28765 {
28766 r = convert_6bit_to_8bit_color_shift_arg(r);
28767 g = convert_6bit_to_8bit_color_shift_arg(g);
28768 b = convert_6bit_to_8bit_color_shift_arg(b);
28769 }
28770 bool m = (SH::read_stack(ri->sp + 0) / 10000);
28771 doGFXMonohue(r,g,b,m);
28772 }
28773
28774 66 void FFScript::clearTint()
28775 {
28776 66 doClearTint();
28777 66 }
28778
28779 3560 void FFScript::Tint()
28780 {
28781 3560 int32_t r = SH::read_stack(ri->sp + 2) / 10000;
28782 3560 int32_t g = SH::read_stack(ri->sp + 1) / 10000;
28783 3560 int32_t b = SH::read_stack(ri->sp + 0) / 10000;
28784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3560 times.
3560 if (!scripting_use_8bit_colors)
28785 {
28786 3560 r = convert_6bit_to_8bit_color_shift_arg(r);
28787 3560 g = convert_6bit_to_8bit_color_shift_arg(g);
28788 3560 b = convert_6bit_to_8bit_color_shift_arg(b);
28789 3560 }
28790 3560 doTint(r,g,b);
28791 3560 }
28792
28793 void FFScript::do_fx_zap(const bool v)
28794 {
28795 int32_t out = SH::get_arg(sarg1, v);
28796
28797 if ( out ) { FFScript::do_zapout(); }
28798 else FFScript::do_zapin();
28799 }
28800
28801 void FFScript::do_fx_wavy(const bool v)
28802 {
28803 int32_t out = SH::get_arg(sarg1, v);
28804
28805 if ( out ) { FFScript::do_wavyout(); }
28806 else FFScript::do_wavyin();
28807 }
28808
28809 541263196 int32_t FFScript::getQuestHeaderInfo(int32_t type)
28810 {
28811 541263196 return quest_format[type];
28812 }
28813
28814 string get_filestr(const bool relative, bool is_file) //Used for 'FileSystem' functions.
28815 {
28816 int32_t strptr = get_register(sarg1);
28817 string user_path;
28818 ArrayH::getString(strptr, user_path, 512);
28819
28820 if (!relative)
28821 {
28822 // Kill leading '/'
28823 size_t first = user_path.find_first_not_of('/');
28824 if (first != string::npos)
28825 user_path = user_path.substr(first, string::npos);
28826
28827 // Kill trailing '/'
28828 size_t last = user_path.find_last_not_of('/');
28829 if (last != string::npos)
28830 user_path = user_path.substr(0, last + 1);
28831
28832 return user_path;
28833 }
28834
28835 if (auto r = parse_user_path(user_path, is_file); !r)
28836 {
28837 scripting_log_error_with_context("Error: {}", r.error());
28838 return "";
28839 } else return r.value();
28840 }
28841
28842 void FFScript::do_checkdir(const bool is_dir)
28843 {
28844 string resolved_path = get_filestr(get_qr(qr_BITMAP_AND_FILESYSTEM_PATHS_ALWAYS_RELATIVE), false);
28845 set_register(sarg1, !resolved_path.empty() && checkPath(resolved_path.c_str(), is_dir) ? 10000 : 0);
28846 }
28847
28848 void FFScript::do_fs_remove()
28849 {
28850 string resolved_path = get_filestr(true, true);
28851 set_register(sarg1, !resolved_path.empty() && remove(resolved_path.c_str()) ? 0 : 10000);
28852 }
28853
28854 110 void FFScript::Play_Level_Music()
28855 {
28856 110 int32_t m = hero_scr->screen_midi;
28857
28858
1/6
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
110 switch(m)
28859 {
28860 case -2:
28861 music_stop();
28862 break;
28863
28864 case -1:
28865 110 play_DmapMusic();
28866 110 break;
28867
28868 case 1:
28869 jukebox(ZC_MIDI_OVERWORLD);
28870 break;
28871
28872 case 2:
28873 jukebox(ZC_MIDI_DUNGEON);
28874 break;
28875
28876 case 3:
28877 jukebox(ZC_MIDI_LEVEL9);
28878 break;
28879
28880 default:
28881 if(m>=4 && m<4+MAXCUSTOMMIDIS)
28882 jukebox(m+MIDIOFFSET_MAPSCR);
28883 else
28884 music_stop();
28885 }
28886 110 }
28887
28888 100 void FFScript::do_warp_ex(bool v)
28889 {
28890 100 int32_t zscript_array_ptr = SH::get_arg(sarg1, v);
28891 100 ArrayManager am(zscript_array_ptr);
28892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if(am.invalid()) return;
28893 100 int32_t zscript_array_size = am.size();
28894
1/2
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
100 switch(zscript_array_size)
28895 {
28896 case 8: // {int32_t type, int32_t dmap, int32_t screen, int32_t x, int32_t y, int32_t effect, int32_t sound, int32_t flags}
28897 case 9: // {int32_t type, int32_t dmap, int32_t screen, int32_t x, int32_t y, int32_t effect, int32_t sound, int32_t flags, int32_t dir}
28898 {
28899 100 int32_t tmpwarp[9]={0};
28900
2/2
✓ Branch 0 taken 800 times.
✓ Branch 1 taken 100 times.
900 for ( int32_t q = 0; q < 8; q++ )
28901 {
28902 800 tmpwarp[q] = (am.get(q)/10000);
28903 800 }
28904
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 74 times.
100 tmpwarp[wexDir] = zscript_array_size < 9 ? -1 : (am.get(8)/10000);\
28905
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if ( ((unsigned)tmpwarp[1]) >= MAXDMAPS )
28906 {
28907 Z_scripterrlog("Invalid DMap ID (%d) passed to WarpEx(). Aborting.\n", tmpwarp[1]);
28908 return;
28909 }
28910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if ( ((unsigned)tmpwarp[2]) >= MAPSCRS )
28911 {
28912 Z_scripterrlog("Invalid Screen Index (%d) passed to WarpEx(). Aborting.\n", tmpwarp[2]);
28913 return;
28914 }
28915 //Extra sanity guard.
28916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if ( map_screen_index(DMaps[tmpwarp[1]].map, tmpwarp[2] + DMaps[tmpwarp[1]].xoff) >= (int32_t)TheMaps.size() )
28917 {
28918 Z_scripterrlog("Invalid destination passed to WarpEx(). Aborting.\n");
28919 return;
28920 }
28921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 if(get_qr(qr_OLD_BROKEN_WARPEX_MUSIC))
28922 {
28923
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 96 times.
100 SETFLAG(tmpwarp[wexFlags],warpFlagFORCECONTINUEMUSIC,tmpwarp[wexFlags]&warpFlagFORCERESETMUSIC);
28924 100 TOGGLEFLAG(tmpwarp[wexFlags],warpFlagFORCERESETMUSIC);
28925 100 }
28926 //If we passed the sanity checks, populate the FFCore array and begin the action!
28927
2/2
✓ Branch 0 taken 900 times.
✓ Branch 1 taken 100 times.
1000 for ( int32_t q = 0; q < wexActive; q++ )
28928 {
28929 900 FFCore.warpex[q] = tmpwarp[q];
28930 900 }
28931 100 FFCore.warpex[wexActive] = 1;
28932 100 break;
28933 }
28934
28935 default:
28936 {
28937 scripting_log_error_with_context("Array supplied is the wrong size! The array size was: %d, and valid sizes are 8 and 9.", zscript_array_size);
28938 break;
28939 }
28940 }
28941 100 }
28942
28943 ///////////////////////////////
28944 //* SCRIPT ENGINE FUNCTIONS *//
28945 ////////////////////////////////////////////////////////////////////////////
28946
28947 void FFScript::clearRunningItemScripts()
28948 {
28949 //for ( byte q = 0; q < 256; q++ ) runningItemScripts[q] = 0;
28950 }
28951
28952
28953 12137 void FFScript::warpScriptCheck()
28954 {
28955
2/2
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 11541 times.
12137 if(get_qr(qr_SCRIPTDRAWSINWARPS))
28956 {
28957 596 FFCore.runWarpScripts(false);
28958 596 FFCore.runWarpScripts(true); //Waitdraw
28959 596 }
28960
3/4
✓ Branch 0 taken 839 times.
✓ Branch 1 taken 10702 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 839 times.
11541 else if(get_qr(qr_PASSIVE_SUBSCRIPT_RUNS_WHEN_GAME_IS_FROZEN) && doscript(ScriptType::ScriptedPassiveSubscreen))
28961 {
28962
1/2
✓ Branch 0 taken 839 times.
✗ Branch 1 not taken.
839 if(DMaps[cur_dmap].passive_sub_script != 0)
28963 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, DMaps[cur_dmap].passive_sub_script, cur_dmap);
28964
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 839 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
839 if (waitdraw(ScriptType::ScriptedPassiveSubscreen) && DMaps[cur_dmap].passive_sub_script != 0 && doscript(ScriptType::ScriptedPassiveSubscreen))
28965 {
28966 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, DMaps[cur_dmap].passive_sub_script, cur_dmap);
28967 waitdraw(ScriptType::ScriptedPassiveSubscreen) = false;
28968 }
28969 839 }
28970 12137 }
28971
28972 1192 void FFScript::runWarpScripts(bool waitdraw)
28973 {
28974
2/2
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 596 times.
1192 if(waitdraw)
28975 {
28976
3/4
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 242 times.
✓ Branch 3 taken 354 times.
596 if ((!( FFCore.system_suspend[susptGLOBALGAME] )) && FFCore.waitdraw(ScriptType::Global, GLOBAL_SCRIPT_GAME))
28977 {
28978 354 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_GAME, GLOBAL_SCRIPT_GAME);
28979 354 FFCore.waitdraw(ScriptType::Global, GLOBAL_SCRIPT_GAME) = false;
28980 354 }
28981
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 596 times.
596 if ( !FFCore.system_suspend[susptITEMSCRIPTENGINE] )
28982 {
28983 596 FFCore.itemScriptEngineOnWaitdraw();
28984 596 }
28985
2/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
596 if ( (!( FFCore.system_suspend[susptHEROACTIVE] )) && FFCore.waitdraw(ScriptType::Hero) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
28986 {
28987 ZScriptVersion::RunScript(ScriptType::Hero, SCRIPT_HERO_ACTIVE);
28988 FFCore.waitdraw(ScriptType::Hero) = false;
28989 }
28990
2/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
596 if ( (!( FFCore.system_suspend[susptDMAPSCRIPT] )) && FFCore.waitdraw(ScriptType::DMap) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
28991 {
28992 ZScriptVersion::RunScript(ScriptType::DMap, DMaps[cur_dmap].script,cur_dmap);
28993 FFCore.waitdraw(ScriptType::DMap) = false;
28994 }
28995
4/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 595 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
596 if ( (!( FFCore.system_suspend[susptDMAPSCRIPT] )) && FFCore.waitdraw(ScriptType::ScriptedPassiveSubscreen) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
28996 {
28997 1 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, DMaps[cur_dmap].passive_sub_script,cur_dmap);
28998 1 FFCore.waitdraw(ScriptType::ScriptedPassiveSubscreen) = false;
28999 1 }
29000 //no doscript check here, becauseb of preload? Do we want to write doscript here? -Z 13th July, 2019
29001
2/4
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
596 if (FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && !FFCore.system_suspend[susptSCREENSCRIPTS])
29002 {
29003 1192 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
29004
3/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 590 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
596 if (scr->script != 0 && FFCore.waitdraw(ScriptType::Screen, scr->screen) && scr->preloadscript)
29005 {
29006 ZScriptVersion::RunScript(ScriptType::Screen, scr->script, scr->screen);
29007 FFCore.waitdraw(ScriptType::Screen, scr->screen) = 0;
29008 }
29009 596 });
29010 596 }
29011 596 }
29012 else
29013 {
29014
2/4
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
596 if ((!( FFCore.system_suspend[susptGLOBALGAME] )) && FFCore.doscript(ScriptType::Global, GLOBAL_SCRIPT_GAME))
29015 {
29016 596 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_GAME, GLOBAL_SCRIPT_GAME);
29017 596 }
29018
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 596 times.
596 if ( !FFCore.system_suspend[susptITEMSCRIPTENGINE] )
29019 {
29020 596 FFCore.itemScriptEngine();
29021 596 }
29022
4/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 564 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
596 if ((!( FFCore.system_suspend[susptHEROACTIVE] )) && doscript(ScriptType::Hero) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255)
29023 {
29024 32 ZScriptVersion::RunScript(ScriptType::Hero, SCRIPT_HERO_ACTIVE);
29025 32 }
29026
3/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 596 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 596 times.
596 if ( (!( FFCore.system_suspend[susptDMAPSCRIPT] )) && doscript(ScriptType::DMap) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
29027 {
29028 596 ZScriptVersion::RunScript(ScriptType::DMap, DMaps[cur_dmap].script,cur_dmap);
29029 596 }
29030
3/6
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 596 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 596 times.
596 if ( (!( FFCore.system_suspend[susptDMAPSCRIPT] )) && FFCore.doscript(ScriptType::ScriptedPassiveSubscreen) && FFCore.getQuestHeaderInfo(vZelda) >= 0x255 )
29031 {
29032 596 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, DMaps[cur_dmap].passive_sub_script,cur_dmap);
29033 596 }
29034
2/4
✓ Branch 0 taken 596 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 596 times.
596 if (FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && !FFCore.system_suspend[susptSCREENSCRIPTS])
29035 {
29036 1192 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
29037
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 590 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
596 if (scr->script != 0 && scr->preloadscript)
29038 {
29039 ZScriptVersion::RunScript(ScriptType::Screen, scr->script, scr->screen);
29040 }
29041 596 });
29042 596 }
29043 }
29044 1192 }
29045
29046 36286810 void FFScript::runF6Engine()
29047 {
29048
5/6
✓ Branch 0 taken 36284971 times.
✓ Branch 1 taken 1839 times.
✓ Branch 2 taken 59 times.
✓ Branch 3 taken 36284912 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 59 times.
36286810 if(!Quit && (GameFlags&GAMEFLAG_TRYQUIT) && !(GameFlags&GAMEFLAG_F6SCRIPT_ACTIVE))
29049 {
29050
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 47 times.
59 if(globalscripts[GLOBAL_SCRIPT_F6]->valid())
29051 {
29052 //Incase this was called mid-another script, store ref data
29053 12 push_ri();
29054 //
29055 12 clear_bitmap(f6_menu_buf);
29056 12 blit(framebuf, f6_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29057 12 initZScriptGlobalScript(GLOBAL_SCRIPT_F6);
29058 12 int32_t openingwipe = black_opening_count;
29059 12 int32_t openingshape = black_opening_shape;
29060 12 black_opening_count = 0; //No opening wipe during F6 menu
29061
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(black_opening_shape==bosFADEBLACK) black_fade(0);
29062 12 GameFlags |= GAMEFLAG_F6SCRIPT_ACTIVE;
29063 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29064 12 pause_all_sfx();
29065
29066 12 auto& data = get_script_engine_data(ScriptType::Global, GLOBAL_SCRIPT_F6);
29067
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 while (data.doscript)
29068 {
29069 12 script_drawing_commands.Clear();
29070 12 load_control_state();
29071 12 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_F6, GLOBAL_SCRIPT_F6);
29072
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (data.waitdraw)
29073 {
29074 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_F6, GLOBAL_SCRIPT_F6);
29075 data.waitdraw = false;
29076 }
29077 //Draw
29078 12 clear_bitmap(framebuf);
29079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if( !FFCore.system_suspend[susptCOMBOANIM] ) animate_combos();
29080 12 doScriptMenuDraws();
29081 //
29082 12 advanceframe(true,true,false);
29083
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(Quit) break; //Something quit, end script running
29084 }
29085 12 resume_all_sfx();
29086 12 script_drawing_commands.Clear();
29087 //script_drawing_commands.push_commands(tmpDrawCommands);
29088 12 GameFlags &= ~GAMEFLAG_F6SCRIPT_ACTIVE;
29089 //Restore opening wipe
29090 12 black_opening_count = openingwipe;
29091 12 black_opening_shape = openingshape;
29092
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(openingshape == bosFADEBLACK)
29093 {
29094 refreshTints();
29095 memcpy(tempblackpal, RAMpal, PAL_SIZE*sizeof(RGB));
29096 }
29097 //Restore script refinfo
29098 12 pop_ri();
29099 //
29100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(!Quit)
29101 {
29102
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(!get_qr(qr_NOCONTINUE))
29103 12 f_Quit(qQUIT);
29104 12 }
29105 12 }
29106 47 else f_Quit(qQUIT);
29107 59 zc_readkey(KEY_F6);
29108 59 GameFlags &= ~GAMEFLAG_TRYQUIT;
29109 59 }
29110 36286810 }
29111 48 void FFScript::runOnDeathEngine()
29112 {
29113
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 17 times.
48 if(!playerscripts[SCRIPT_HERO_DEATH]->valid()) return; //No script to run
29114 17 clear_bitmap(script_menu_buf);
29115 17 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29116 17 initZScriptHeroScripts();
29117 17 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29118 17 kill_sfx(); //No need to pause/resume; the player is dead.
29119 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29120
29121 17 auto& data = get_script_engine_data(ScriptType::Hero);
29122
4/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 818 times.
✓ Branch 2 taken 818 times.
✓ Branch 3 taken 17 times.
835 while (data.doscript && !Quit)
29123 {
29124 818 script_drawing_commands.Clear();
29125 818 load_control_state();
29126 818 ZScriptVersion::RunScript(ScriptType::Hero, SCRIPT_HERO_DEATH);
29127
1/2
✓ Branch 0 taken 818 times.
✗ Branch 1 not taken.
818 if (data.waitdraw)
29128 {
29129 ZScriptVersion::RunScript(ScriptType::Hero, SCRIPT_HERO_DEATH);
29130 data.waitdraw = false;
29131 }
29132 //Draw
29133 818 clear_bitmap(framebuf);
29134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 818 times.
818 if( !FFCore.system_suspend[susptCOMBOANIM] ) animate_combos();
29135 818 doScriptMenuDraws();
29136 //
29137 818 advanceframe(true);
29138 }
29139 17 script_drawing_commands.Clear();
29140 //script_drawing_commands.push_commands(tmpDrawCommands);
29141 17 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29142 48 }
29143 435 void FFScript::runOnLaunchEngine()
29144 {
29145
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 15 times.
435 if(!globalscripts[GLOBAL_SCRIPT_ONLAUNCH]->valid()) return; //No script to run
29146 //Do NOT blit the prior screen to this bitmap; that would be the TITLE SCREEN.
29147 15 clear_to_color(script_menu_buf,BLACK);
29148 15 initZScriptGlobalScript(GLOBAL_SCRIPT_ONLAUNCH);
29149 15 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29150 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29151
29152 15 auto& data = get_script_engine_data(ScriptType::Global, GLOBAL_SCRIPT_ONLAUNCH);
29153
4/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 15 times.
30 while (data.doscript && !Quit)
29154 {
29155 15 script_drawing_commands.Clear();
29156 15 load_control_state();
29157 15 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_ONLAUNCH, GLOBAL_SCRIPT_ONLAUNCH);
29158
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (data.waitdraw)
29159 {
29160 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_ONLAUNCH, GLOBAL_SCRIPT_ONLAUNCH);
29161 data.waitdraw = false;
29162 }
29163 //Draw
29164 15 clear_bitmap(framebuf);
29165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if( !FFCore.system_suspend[susptCOMBOANIM] ) animate_combos();
29166
29167 15 doScriptMenuDraws();
29168 //
29169 15 advanceframe(true);
29170 }
29171 15 script_drawing_commands.Clear();
29172 //script_drawing_commands.push_commands(tmpDrawCommands);
29173 15 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29174 435 }
29175 10 bool FFScript::runGenericFrozenEngine(const word script, const int32_t *init_data)
29176 {
29177 10 user_genscript& scr = user_genscript::get(script);
29178
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if(script < 1 || script >= NUMSCRIPTSGENERIC) return false;
29179
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(init_data)
29180 {
29181 for(int q = 0; q < 8; ++q)
29182 scr.initd[q] = init_data[q];
29183 }
29184
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(!genericscripts[script]->valid()) return false; //No script to run
29185
29186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(gen_frozen_index >= 400) // Experimentally tested to crash (stack overflow) at 500 for me -Em
29187 {
29188 Z_scripterrlog("Failed to run frozen generic script; too many (%zu) frozen scripts running already! Possible infinite recursion?\n", gen_frozen_index);
29189 return false;
29190 }
29191 //Store script refinfo
29192 10 push_ri();
29193 10 int local_i = int(gen_frozen_index++);
29194 10 reset_script_engine_data(ScriptType::GenericFrozen, local_i);
29195 //run script
29196 10 uint32_t fl = GameFlags & GAMEFLAG_SCRIPTMENU_ACTIVE;
29197 10 BITMAP* tmpbuf = script_menu_buf;
29198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(fl)
29199 {
29200 script_menu_buf = create_bitmap_ex(8, framebuf->w, framebuf->h);
29201 }
29202 10 clear_bitmap(script_menu_buf);
29203 10 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29204 10 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29205 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29206
4/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1542 times.
✓ Branch 2 taken 1542 times.
✓ Branch 3 taken 10 times.
1552 while(doscript(ScriptType::GenericFrozen, local_i) && !Quit)
29207 {
29208 1542 script_drawing_commands.Clear();
29209 1542 load_control_state();
29210 1542 ZScriptVersion::RunScript(ScriptType::GenericFrozen, script, local_i);
29211 //Draw
29212 1542 clear_bitmap(framebuf);
29213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1542 times.
1542 if( !FFCore.system_suspend[susptCOMBOANIM] ) animate_combos();
29214 1542 doScriptMenuDraws();
29215 //
29216 1542 advanceframe(true);
29217 }
29218 10 script_drawing_commands.Clear();
29219 //script_drawing_commands.push_commands(tmpDrawCommands);
29220 //clear
29221 10 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(fl)
29223 {
29224 GameFlags |= fl;
29225 destroy_bitmap(script_menu_buf);
29226 script_menu_buf = tmpbuf;
29227 }
29228 10 clear_script_engine_data(ScriptType::GenericFrozen, local_i);
29229 10 --gen_frozen_index;
29230 //Restore script refinfo
29231 10 pop_ri();
29232 10 return true;
29233 10 }
29234
29235 1479 bool FFScript::runScriptedActiveSubscreen()
29236 {
29237 1479 word activesubscript = DMaps[cur_dmap].active_sub_script;
29238
3/4
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 1438 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41 times.
1479 if(!activesubscript || !dmapscripts[activesubscript]->valid()) return false; //No script to run
29239 41 word passivesubscript = DMaps[cur_dmap].passive_sub_script;
29240 41 word dmapactivescript = DMaps[cur_dmap].script;
29241 41 clear_bitmap(script_menu_buf);
29242 41 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29243 41 initZScriptScriptedActiveSubscreen();
29244 41 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29245 41 word script_dmap = cur_dmap;
29246 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29247 41 pause_all_sfx();
29248 41 auto& data = get_script_engine_data(ScriptType::ScriptedActiveSubscreen);
29249
4/4
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 6772 times.
✓ Branch 2 taken 6772 times.
✓ Branch 3 taken 41 times.
6813 while (data.doscript && !Quit)
29250 {
29251 6772 script_drawing_commands.Clear();
29252 6772 load_control_state();
29253
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6772 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6772 if(get_qr(qr_DMAP_ACTIVE_RUNS_DURING_ACTIVE_SUBSCRIPT) && DMaps[script_dmap].script != 0 && doscript(ScriptType::DMap))
29254 {
29255 ZScriptVersion::RunScript(ScriptType::DMap, dmapactivescript, script_dmap);
29256 }
29257
4/6
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 6632 times.
✓ Branch 2 taken 140 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 140 times.
6772 if(get_qr(qr_PASSIVE_SUBSCRIPT_RUNS_DURING_ACTIVE_SUBSCRIPT)!=0 && DMaps[script_dmap].passive_sub_script != 0 && FFCore.doscript(ScriptType::ScriptedPassiveSubscreen))
29258 {
29259 140 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, passivesubscript, script_dmap);
29260 140 }
29261 6772 ZScriptVersion::RunScript(ScriptType::ScriptedActiveSubscreen, activesubscript, script_dmap);
29262
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 6772 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6772 if(waitdraw(ScriptType::DMap) && (get_qr(qr_DMAP_ACTIVE_RUNS_DURING_ACTIVE_SUBSCRIPT) && DMaps[script_dmap].script != 0 && doscript(ScriptType::DMap)))
29263 {
29264 ZScriptVersion::RunScript(ScriptType::DMap, dmapactivescript, script_dmap);
29265 waitdraw(ScriptType::DMap) = false;
29266 }
29267
5/8
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 6633 times.
✓ Branch 2 taken 139 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 139 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 139 times.
6772 if(waitdraw(ScriptType::ScriptedPassiveSubscreen) && (get_qr(qr_PASSIVE_SUBSCRIPT_RUNS_DURING_ACTIVE_SUBSCRIPT)!=0 && DMaps[script_dmap].passive_sub_script != 0 && FFCore.doscript(ScriptType::ScriptedPassiveSubscreen)))
29268 {
29269 139 ZScriptVersion::RunScript(ScriptType::ScriptedPassiveSubscreen, passivesubscript, script_dmap);
29270 139 waitdraw(ScriptType::ScriptedPassiveSubscreen) = false;
29271 139 }
29272
3/4
✓ Branch 0 taken 5472 times.
✓ Branch 1 taken 1300 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5472 times.
6772 if (data.waitdraw && data.doscript)
29273 {
29274 5472 ZScriptVersion::RunScript(ScriptType::ScriptedActiveSubscreen, activesubscript, script_dmap);
29275 5472 data.waitdraw = false;
29276 5472 }
29277 //Draw
29278 6772 clear_bitmap(framebuf);
29279
2/4
✓ Branch 0 taken 6772 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6772 times.
6772 if(cur_dmap == script_dmap && ( !FFCore.system_suspend[susptCOMBOANIM] ) ) animate_combos();
29280 6772 doScriptMenuDraws();
29281 //
29282 6772 advanceframe(true);
29283 //Handle warps; run game_loop once!
29284
1/2
✓ Branch 0 taken 6772 times.
✗ Branch 1 not taken.
6772 if(cur_dmap != script_dmap)
29285 {
29286 activesubscript = DMaps[cur_dmap].active_sub_script;
29287 if(!activesubscript || !dmapscripts[activesubscript]->valid()) return true; //No script to run
29288 passivesubscript = DMaps[cur_dmap].passive_sub_script;
29289 dmapactivescript = DMaps[cur_dmap].script;
29290 script_dmap = cur_dmap;
29291 //Reset the background image
29292 game_loop();
29293 clear_bitmap(script_menu_buf);
29294 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29295 //Now loop without advancing frame, so that the subscreen script can draw immediately.
29296 }
29297 }
29298 41 resume_all_sfx();
29299 41 script_drawing_commands.Clear();
29300 //script_drawing_commands.push_commands(tmpDrawCommands);
29301 41 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29302 41 GameFlags |= GAMEFLAG_RESET_GAME_LOOP;
29303 41 return true;
29304 1479 }
29305 1119 bool FFScript::runOnMapScriptEngine()
29306 {
29307 1119 word onmap_script = DMaps[cur_dmap].onmap_script;
29308
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1112 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
1119 if(!onmap_script || !dmapscripts[onmap_script]->valid()) return false; //No script to run
29309 7 clear_bitmap(script_menu_buf);
29310 7 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29311 7 initZScriptOnMapScript();
29312 7 GameFlags |= GAMEFLAG_SCRIPTMENU_ACTIVE;
29313 7 word script_dmap = cur_dmap;
29314 //auto tmpDrawCommands = script_drawing_commands.pop_commands();
29315 7 pause_all_sfx();
29316
29317 7 auto& data = get_script_engine_data(ScriptType::OnMap);
29318
4/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 909 times.
✓ Branch 2 taken 909 times.
✓ Branch 3 taken 7 times.
916 while (data.doscript && !Quit)
29319 {
29320 909 script_drawing_commands.Clear();
29321 909 load_control_state();
29322 909 ZScriptVersion::RunScript(ScriptType::OnMap, onmap_script, script_dmap);
29323
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 909 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
909 if (data.waitdraw && data.doscript)
29324 {
29325 ZScriptVersion::RunScript(ScriptType::OnMap, onmap_script, script_dmap);
29326 data.waitdraw = false;
29327 }
29328 //Draw
29329 909 clear_bitmap(framebuf);
29330
2/4
✓ Branch 0 taken 909 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 909 times.
909 if(cur_dmap == script_dmap && ( !FFCore.system_suspend[susptCOMBOANIM] ) ) animate_combos();
29331 909 doScriptMenuDraws();
29332 //
29333 909 advanceframe(true);
29334 //Handle warps; run game_loop once!
29335
1/2
✓ Branch 0 taken 909 times.
✗ Branch 1 not taken.
909 if(cur_dmap != script_dmap)
29336 {
29337 onmap_script = DMaps[cur_dmap].onmap_script;
29338 if(!onmap_script || !dmapscripts[onmap_script]->valid()) return true; //No script to run
29339 script_dmap = cur_dmap;
29340 //Reset the background image
29341 game_loop();
29342 clear_bitmap(script_menu_buf);
29343 blit(framebuf, script_menu_buf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29344 //Now loop without advancing frame, so that the subscreen script can draw immediately.
29345 }
29346 }
29347 7 resume_all_sfx();
29348 7 script_drawing_commands.Clear();
29349 //script_drawing_commands.push_commands(tmpDrawCommands);
29350 7 GameFlags &= ~GAMEFLAG_SCRIPTMENU_ACTIVE;
29351 7 GameFlags |= GAMEFLAG_RESET_GAME_LOOP;
29352 7 return true;
29353 1119 }
29354
29355 10068 void FFScript::doScriptMenuDraws()
29356 {
29357
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 10056 times.
10068 BITMAP* menu_buf = ((GameFlags & GAMEFLAG_F6SCRIPT_ACTIVE) != 0) ? f6_menu_buf : script_menu_buf;
29358 10068 blit(menu_buf, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
29359 //Script draws
29360 10068 do_script_draws(framebuf, origin_scr, 0, playing_field_offset);
29361 10068 }
29362
29363 277 void FFScript::runOnSaveEngine()
29364 {
29365
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 7 times.
277 if(globalscripts[GLOBAL_SCRIPT_ONSAVE]->valid())
29366 {
29367 7 push_ri();
29368 //Prevent getting here via Quit from causing a forced-script-quit after 1000 commands!
29369 7 int32_t tQuit = Quit;
29370 7 Quit = 0;
29371 //
29372 7 initZScriptGlobalScript(GLOBAL_SCRIPT_ONSAVE);
29373 7 ZScriptVersion::RunScript(ScriptType::Global, GLOBAL_SCRIPT_ONSAVE, GLOBAL_SCRIPT_ONSAVE);
29374 //
29375 7 pop_ri();
29376 7 Quit = tQuit;
29377 7 }
29378 277 }
29379
29380 16550732 bool FFScript::itemScriptEngine()
29381 {
29382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16550732 times.
16550732 if ( FFCore.system_suspend[susptITEMSCRIPTENGINE] ) return false;
29383
2/2
✓ Branch 0 taken 4236987392 times.
✓ Branch 1 taken 16550732 times.
4253538124 for ( int32_t q = 0; q < MAXITEMS; q++ )
29384 {
29385
29386
3/4
✓ Branch 0 taken 31422766 times.
✓ Branch 1 taken 4205564626 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31422766 times.
4236987392 if ( itemsbuf[q].script <= 0 || itemsbuf[q].script > NUMSCRIPTITEM ) continue; // > NUMSCRIPTITEM as someone could force an invaid script slot!
29387
29388 31422766 auto& data = get_script_engine_data(ScriptType::Item, q);
29389
2/2
✓ Branch 0 taken 14167 times.
✓ Branch 1 taken 31408599 times.
31422766 if ( data.doscript < 1 ) continue;
29390
29391 //Passive items
29392
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14167 times.
14167 if (((itemsbuf[q].flags&item_passive_script)))
29393 {
29394 if(game->item[q] && (get_qr(qr_ITEMSCRIPTSKEEPRUNNING)))
29395 {
29396 if(get_qr(qr_PASSIVE_ITEM_SCRIPT_ONLY_HIGHEST)
29397 && current_item(itemsbuf[q].type) > itemsbuf[q].level)
29398 data.doscript = 0;
29399 else ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q&0xFFF);
29400 if(!data.doscript) //Item script ended. Clear the data, if any remains.
29401 {
29402 data.clear_ref();
29403 data.waitdraw = false;
29404 FFScript::deallocateAllScriptOwned(ScriptType::Item, q);
29405 }
29406 }
29407 }
29408 else
29409 {
29410
29411 //Normal Items
29412 /*! What happens here: When an item script is first run by the user using that utem, the script runs for one frame.
29413 After executing RunScript(), item_doscript is set to '1' in hero.cpp.
29414 If the quest allows the item to continue running, the itemScriptEngine() function ignores running the
29415 same item script (again) that frame, and insteads increments item_doscript to '2'.
29416 If item_doscript == 2, then we know we are on the second frame, and we run it perpetually.
29417 If the QR to enable item scripts to run for more than one frame is not enabled, then item_doscript is set to '0'.
29418 If the item flag 'PERPETUAL SCRIPT' is enabled, then we ignore the lack of item_doscript==2.
29419 This allows passive item scripts to function.
29420 */
29421
29422 14167 auto& data = get_script_engine_data(ScriptType::Item, q);
29423
29424
2/2
✓ Branch 0 taken 662 times.
✓ Branch 1 taken 13505 times.
14167 if ( data.doscript == 1 ) // FIrst frame, normally set in hero.cpp
29425 {
29426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 662 times.
662 if ( get_qr(qr_ITEMSCRIPTSKEEPRUNNING) )
29427 {
29428 662 data.doscript = 2;
29429 662 }
29430 662 }
29431
1/2
✓ Branch 0 taken 13505 times.
✗ Branch 1 not taken.
13505 else if (data.doscript == 2) //Second frame and later, if scripts continue to run.
29432 {
29433 13505 ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q&0xFFF);
29434 13505 }
29435 else if (data.doscript == 3) //Run via itemdata->RunScript
29436 {
29437 if ( (get_qr(qr_ITEMSCRIPTSKEEPRUNNING)) )
29438 {
29439 data.doscript = 2; //Reduce to normal run status
29440 }
29441 else
29442 {
29443 ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q & 0xFFF);
29444 data.doscript = 0;
29445 }
29446 }
29447 else if(data.doscript==4) //Item set itself false, kill script and clear data here
29448 {
29449 data.doscript = 0;
29450 }
29451
2/2
✓ Branch 0 taken 13490 times.
✓ Branch 1 taken 677 times.
14167 if(data.doscript==0) //Item script ended. Clear the data, if any remains.
29452 {
29453 677 data.clear_ref();
29454 677 data.waitdraw = false;
29455 677 FFScript::deallocateAllScriptOwned(ScriptType::Item, q);
29456 677 }
29457 }
29458 14167 }
29459 16550732 return false;
29460 16550732 }
29461
29462 17092109 bool FFScript::itemScriptEngineOnWaitdraw()
29463 {
29464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17092109 times.
17092109 if ( FFCore.system_suspend[susptITEMSCRIPTENGINE] ) return false;
29465
2/2
✓ Branch 0 taken 4375579904 times.
✓ Branch 1 taken 17092109 times.
4392672013 for ( int32_t q = 0; q < MAXITEMS; q++ )
29466 {
29467
3/4
✓ Branch 0 taken 33430535 times.
✓ Branch 1 taken 4342149369 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 33430535 times.
4375579904 if ( itemsbuf[q].script <= 0 || itemsbuf[q].script > NUMSCRIPTITEM ) continue; // > NUMSCRIPTITEM as someone could force an invaid script slot!
29468
29469 33430535 auto& data = get_script_engine_data(ScriptType::Item, q);
29470
29471
2/2
✓ Branch 0 taken 13491 times.
✓ Branch 1 taken 33417044 times.
33430535 if ( data.doscript < 1 ) continue;
29472
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13491 times.
13491 if (!data.waitdraw) continue;
29473 else data.waitdraw = false;
29474
29475 /*! What happens here: When an item script is first run by the user using that utem, the script runs for one frame.
29476 After executing RunScript(), item_doscript is set to '1' in hero.cpp.
29477 If the quest allows the item to continue running, the itemScriptEngine() function ignores running the
29478 same item script (again) that frame, and insteads increments item_doscript to '2'.
29479 If item_doscript == 2, then we know we are on the second frame, and we run it perpetually.
29480 If the QR to enable item scripts to run for more than one frame is not enabled, then item_doscript is set to '0'.
29481 If the item flag 'PERPETUAL SCRIPT' is enabled, then we ignore the lack of item_doscript==2.
29482 This allows passive item scripts to function.
29483 */
29484 //Passive items
29485 if ((itemsbuf[q].flags&item_passive_script))
29486 {
29487 if(game->item[q] && (get_qr(qr_ITEMSCRIPTSKEEPRUNNING)))
29488 {
29489 if(get_qr(qr_PASSIVE_ITEM_SCRIPT_ONLY_HIGHEST)
29490 && current_item(itemsbuf[q].type) > itemsbuf[q].level)
29491 data.doscript = 0;
29492 else ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q&0xFFF);
29493 if(!data.doscript) //Item script ended. Clear the data, if any remains.
29494 {
29495 data.clear_ref();
29496 data.waitdraw = false;
29497 FFScript::deallocateAllScriptOwned(ScriptType::Item, q);
29498 }
29499 }
29500 }
29501 else
29502 {
29503 //Normal items
29504 if ( data.doscript == 1 ) // FIrst frame, normally set in hero.cpp
29505 {
29506 if ( get_qr(qr_ITEMSCRIPTSKEEPRUNNING) )
29507 {
29508 data.doscript = 2;
29509 }
29510 else data.doscript = 0;
29511 }
29512 else if (data.doscript == 2) //Second frame and later, if scripts continue to run.
29513 {
29514 ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q&0xFFF);
29515 }
29516 else if (data.doscript == 3) //Run via itemdata->RunScript
29517 {
29518 if ( (get_qr(qr_ITEMSCRIPTSKEEPRUNNING)) )
29519 {
29520 data.doscript = 2; //Reduce to normal run status
29521 }
29522 else
29523 {
29524 ZScriptVersion::RunScript(ScriptType::Item, itemsbuf[q].script, q & 0xFFF);
29525 data.doscript = 0;
29526 }
29527 }
29528 else if(data.doscript==4) //Item set itself false, kill script and clear data here.
29529 {
29530 data.doscript = 0;
29531 }
29532 if(!data.doscript) //Item script ended. Clear the data, if any remains.
29533 {
29534 data.clear_ref();
29535 data.waitdraw = false;
29536 FFScript::deallocateAllScriptOwned(ScriptType::Item, q);
29537 }
29538 }
29539 }
29540 17092109 return false;
29541 17092109 }
29542 15347515 void FFScript::npcScriptEngineOnWaitdraw()
29543 {
29544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15347515 times.
15347515 if ( FFCore.system_suspend[susptNPCSCRIPTS] ) return;
29545 15347515 guys.run_script(MODE_WAITDRAW);
29546 15347515 }
29547
29548 14834064 void FFScript::eweaponScriptEngine()
29549 {
29550
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14834064 times.
14834064 if ( FFCore.system_suspend[susptEWEAPONSCRIPTS] ) return;
29551 14834064 Ewpns.run_script(MODE_NORMAL);
29552 14834064 }
29553
29554 15347515 void FFScript::lweaponScriptEngineOnWaitdraw()
29555 {
29556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15347515 times.
15347515 if ( FFCore.system_suspend[susptLWEAPONSCRIPTS] ) return;
29557 15347515 Lwpns.run_script(MODE_WAITDRAW);
29558 15347515 }
29559
29560 15376822 void FFScript::eweaponScriptEngineOnWaitdraw()
29561 {
29562
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 15376812 times.
15376822 if ( FFCore.system_suspend[susptEWEAPONSCRIPTS] ) return;
29563 15376812 Ewpns.run_script(MODE_WAITDRAW);
29564 15376822 }
29565
29566 14836690 void FFScript::itemSpriteScriptEngine()
29567 {
29568
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14836690 times.
14836690 if ( FFCore.system_suspend[susptITEMSPRITESCRIPTS] ) return;
29569 14836690 items.run_script(MODE_NORMAL);
29570 14836690 }
29571
29572 15379340 void FFScript::itemSpriteScriptEngineOnWaitdraw()
29573 {
29574
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15379340 times.
15379340 if ( FFCore.system_suspend[susptITEMSPRITESCRIPTS] ) return;
29575 15379340 items.run_script(MODE_WAITDRAW);
29576 15379340 }
29577
29578
29579 15 int32_t FFScript::getTime(int32_t type)
29580 {
29581 //struct tm *tm_struct = localtime(time(NULL));
29582 struct tm * tm_struct;
29583 time_t sysRTC;
29584 15 time (&sysRTC);
29585 15 tm_struct = localtime (&sysRTC);
29586 15 int32_t rval = -1;
29587
29588
5/10
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
15 switch(type)
29589 {
29590 case curyear:
29591 {
29592 //Year format starts at 1900, yeat
29593 //A raw read of '2018' would be '118', so we add 1900 to it to derive the actual year.
29594 3 rval = tm_struct->tm_year + 1900; break;
29595
29596 }
29597 case curmonth:
29598 {
29599 //Months start at 0, but we want 1->12
29600 rval = tm_struct->tm_mon +1; break;
29601 }
29602 case curday_month:
29603 {
29604 rval = tm_struct->tm_mday; break;
29605 }
29606 case curday_week:
29607 {
29608 //It seems that weekdays are a value range of 1 to 7.
29609 rval = tm_struct->tm_wday; break;
29610 }
29611 case curhour:
29612 {
29613 3 rval = tm_struct->tm_hour; break;
29614 }
29615 case curminute:
29616 {
29617 3 rval = tm_struct->tm_min; break;
29618 }
29619 case cursecond:
29620 {
29621 3 rval = tm_struct->tm_sec; break;
29622 }
29623 case curdayyear:
29624 {
29625 //The day (n/365) out of the entire year.
29626 3 rval = tm_struct->tm_yday; break;
29627 }
29628 case curDST:
29629 {
29630 //Returns if the user is in a Time Zone with Daylight TIme of some sort.
29631 //View the time.h docs for the actual values of this struct element.
29632 rval = tm_struct->tm_isdst;; break;
29633 }
29634 default:
29635 {
29636 al_trace("Invalid category passed to GetSystemTime(%d)\n",type);
29637 rval = -1; break;
29638 }
29639
29640 }
29641 15 return rval;
29642 }
29643
29644 2511 void FFScript::do_lweapon_delete()
29645 {
29646
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2511 times.
2511 if(auto s=checkLWpn(GET_REF(lwpnref)))
29647 {
29648
1/2
✓ Branch 0 taken 2511 times.
✗ Branch 1 not taken.
2511 if(s==Hero.lift_wpn)
29649 {
29650 delete s;
29651 Hero.lift_wpn = nullptr;
29652 }
29653 2511 else Lwpns.del(s);
29654 2511 }
29655 2511 }
29656
29657 1482 void FFScript::do_eweapon_delete()
29658 {
29659
1/2
✓ Branch 0 taken 1482 times.
✗ Branch 1 not taken.
1482 if(auto s=checkEWpn(GET_REF(ewpnref)))
29660 {
29661 1482 Ewpns.del(s);
29662 1482 }
29663 1482 }
29664
29665 1149 void FFScript::updateIncludePaths()
29666 {
29667 1149 includePaths.clear();
29668 1149 int32_t pos = 0;
29669
2/2
✓ Branch 0 taken 3969 times.
✓ Branch 1 taken 1149 times.
5118 for ( int32_t q = 0; includePathString[pos]; ++q )
29670 {
29671 3969 int32_t dest = 0;
29672 3969 char buf[2048] = {0};
29673
4/4
✓ Branch 0 taken 3882 times.
✓ Branch 1 taken 80994 times.
✓ Branch 2 taken 80907 times.
✓ Branch 3 taken 3969 times.
84876 while(includePathString[pos] != ';' && includePathString[pos])
29674 {
29675 80907 buf[dest] = includePathString[pos];
29676 80907 ++pos;
29677 80907 ++dest;
29678 }
29679 3969 ++pos;
29680
1/2
✓ Branch 0 taken 3969 times.
✗ Branch 1 not taken.
3969 std::string str(buf);
29681
1/2
✓ Branch 0 taken 3969 times.
✗ Branch 1 not taken.
3969 includePaths.push_back(str);
29682 3969 }
29683 1149 }
29684
29685 1149 void FFScript::initIncludePaths()
29686 {
29687 1149 memset(includePathString,0,sizeof(includePathString));
29688 1149 FILE* f = fopen("includepaths.txt", "r");
29689
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 1062 times.
1149 if(f)
29690 {
29691 87 int32_t pos = 0;
29692 int32_t c;
29693 87 do
29694 {
29695 56202 c = fgetc(f);
29696
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 56115 times.
56202 if(c!=EOF)
29697 56115 includePathString[pos++] = c;
29698
2/2
✓ Branch 0 taken 56115 times.
✓ Branch 1 taken 87 times.
112404 }
29699
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 56115 times.
56202 while(c!=EOF && pos<MAX_INCLUDE_PATH_CHARS);
29700
1/2
✓ Branch 0 taken 87 times.
✗ Branch 1 not taken.
87 if(pos<MAX_INCLUDE_PATH_CHARS)
29701 87 includePathString[pos] = '\0';
29702 87 includePathString[MAX_INCLUDE_PATH_CHARS-1] = '\0';
29703 87 fclose(f);
29704 87 }
29705 1062 else strcpy(includePathString, "include/;headers/;scripts/;");
29706 1149 al_trace("Full path string is: ");
29707 1149 safe_al_trace(includePathString);
29708 1149 al_trace("\n");
29709 1149 updateIncludePaths();
29710
29711
2/2
✓ Branch 0 taken 3969 times.
✓ Branch 1 taken 1149 times.
5118 for ( size_t q = 0; q < includePaths.size(); ++q )
29712 {
29713 3969 al_trace("Include path %zu: ",q);
29714 3969 safe_al_trace(includePaths.at(q));
29715 3969 al_trace("\n");
29716 3969 }
29717 1149 }
29718
29719 10 bool FFScript::checkExtension(std::string &filename, const std::string &extension)
29720 //inline bool checkExtension(std::string filename, std::string extension)
29721 {
29722 10 int32_t dot = filename.find_last_of(".");
29723
3/10
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
10 std::string exten = (dot == std::string::npos ? "" : filename.substr(dot, filename.length() - dot));
29724 10 return exten == extension;
29725 10 }
29726
29727 2544 void FFScript::do_strcmp()
29728 {
29729 2544 int32_t arrayptr_a = GET_D(rINDEX);
29730 2544 int32_t arrayptr_b = GET_D(rINDEX2);
29731 2544 string strA;
29732 2544 string strB;
29733
1/2
✓ Branch 0 taken 2544 times.
✗ Branch 1 not taken.
2544 ArrayH::getString(arrayptr_a, strA);
29734
1/2
✓ Branch 0 taken 2544 times.
✗ Branch 1 not taken.
2544 ArrayH::getString(arrayptr_b, strB);
29735
1/2
✓ Branch 0 taken 2544 times.
✗ Branch 1 not taken.
2544 set_register(sarg1, (strcmp(strA.c_str(), strB.c_str()) * 10000));
29736 2544 }
29737
29738 void FFScript::do_stricmp()
29739 {
29740 int32_t arrayptr_a = GET_D(rINDEX);
29741 int32_t arrayptr_b = GET_D(rINDEX2);
29742 string strA;
29743 string strB;
29744 ArrayH::getString(arrayptr_a, strA);
29745 ArrayH::getString(arrayptr_b, strB);
29746 set_register(sarg1, (stricmp(strA.c_str(), strB.c_str()) * 10000));
29747 }
29748
29749 2 void FFScript::do_LowerToUpper(const bool v)
29750 {
29751 2 int32_t arrayptr_a = get_register(sarg1);
29752 2 string strA;
29753
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ArrayH::getString(arrayptr_a, strA);
29754
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 for (char& c : strA)
29755 6 c = std::toupper(c);
29756
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 ArrayH::setArray(arrayptr_a, strA);
29757
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 set_register(sarg1, 10000); // used to return 0 if string was empty.
29758 2 }
29759
29760 void FFScript::do_UpperToLower(const bool v)
29761 {
29762 int32_t arrayptr_a = get_register(sarg1);
29763 string strA;
29764 ArrayH::getString(arrayptr_a, strA);
29765 for (char& c : strA)
29766 c = std::tolower(c);
29767 ArrayH::setArray(arrayptr_a, strA);
29768 set_register(sarg1, 10000); // used to return 0 if string was empty.
29769 }
29770
29771 void FFScript::do_getnpcscript()
29772 {
29773 do_get_script_index_by_name(name_to_slot_index_npcmap);
29774 }
29775
29776 234 void FFScript::do_getcomboscript()
29777 {
29778 234 do_get_script_index_by_name(name_to_slot_index_comboscriptmap);
29779 234 }
29780
29781 137138 void FFScript::do_getgenericscript()
29782 {
29783 137138 do_get_script_index_by_name(name_to_slot_index_genericmap);
29784 137138 }
29785
29786 7914 void FFScript::do_getlweaponscript()
29787 {
29788 7914 do_get_script_index_by_name(name_to_slot_index_lwpnmap);
29789 7914 }
29790 4636 void FFScript::do_geteweaponscript()
29791 {
29792 4636 do_get_script_index_by_name(name_to_slot_index_ewpnmap);
29793 4636 }
29794 void FFScript::do_getheroscript()
29795 {
29796 do_get_script_index_by_name(name_to_slot_index_playermap);
29797 }
29798 void FFScript::do_getglobalscript()
29799 {
29800 do_get_script_index_by_name(name_to_slot_index_globalmap);
29801 }
29802 906 void FFScript::do_getdmapscript()
29803 {
29804 906 do_get_script_index_by_name(name_to_slot_index_dmapmap);
29805 906 }
29806 void FFScript::do_getscreenscript()
29807 {
29808 do_get_script_index_by_name(name_to_slot_index_screenmap);
29809 }
29810 115 void FFScript::do_getitemspritescript()
29811 {
29812 115 do_get_script_index_by_name(name_to_slot_index_itemspritemap);
29813 115 }
29814 //Not assigned to slots at present. If they ever are, then this would get the id of any script (any type) by name. -Z
29815 void FFScript::do_getuntypedscript()
29816 {
29817 set_register(sarg1, 0);
29818 }
29819 void FFScript::do_getsubscreenscript()
29820 {
29821 do_get_script_index_by_name(name_to_slot_index_subscreenmap);
29822 }
29823 void FFScript::do_getnpcbyname()
29824 {
29825 int32_t arrayptr = get_register(sarg1);
29826 string the_string;
29827 int32_t num = -1;
29828 ArrayH::getString(arrayptr, the_string, 256); //What is the max length of a script identifier?
29829
29830 for(int32_t q = 0; q < MAXNPCS; q++)
29831 {
29832 if(!(strcmp(the_string.c_str(), guy_string[q])))
29833 {
29834 num = q;
29835 break;
29836 }
29837 }
29838 set_register(sarg1, (num * 10000));
29839 }
29840 void FFScript::do_getitembyname()
29841 {
29842 int32_t arrayptr = get_register(sarg1);
29843 string the_string;
29844 int32_t num = -1;
29845 ArrayH::getString(arrayptr, the_string, 256); //What is the max length of a script identifier?
29846
29847 for(int32_t q = 0; q < MAXITEMS; q++)
29848 {
29849 if(!(strcmp(the_string.c_str(), item_string[q])))
29850 {
29851 num = q;
29852 break;
29853 }
29854 }
29855 set_register(sarg1, (num * 10000));
29856 }
29857 void FFScript::do_getcombobyname()
29858 {
29859 int32_t arrayptr = get_register(sarg1);
29860 string the_string;
29861 int32_t num = -1;
29862 ArrayH::getString(arrayptr, the_string, 256);
29863
29864 if (!the_string.empty())
29865 {
29866 for(int32_t q = 0; q < MAXCOMBOS; q++)
29867 {
29868 if (the_string == combobuf[q].label)
29869 {
29870 num = q;
29871 break;
29872 }
29873 }
29874 }
29875 set_register(sarg1, (num * 10000));
29876 }
29877 void FFScript::do_getdmapbyname()
29878 {
29879 int32_t arrayptr = get_register(sarg1);
29880 string the_string;
29881 int32_t num = -1;
29882 ArrayH::getString(arrayptr, the_string, 256); //What is the max length of a script identifier?
29883
29884 for(int32_t q = 0; q < MAXDMAPS; q++)
29885 {
29886 if(!(strcmp(the_string.c_str(), DMaps[q].name)))
29887 {
29888 num = q;
29889 break;
29890 }
29891 }
29892 set_register(sarg1, (num * 10000));
29893 }
29894
29895 ////////////////////////
29896 /// String Utilities ///
29897 ////////////////////////
29898 void FFScript::do_ConvertCase(const bool v)
29899 {
29900 int32_t arrayptr_a = get_register(sarg1);
29901 string strA;
29902 ArrayH::getString(arrayptr_a, strA);
29903 for (char& c : strA)
29904 {
29905 if (c < 'a')
29906 c += 32 * (c >= 'A' && c <= 'Z');
29907 else
29908 c -= 32 * (c >= 'a' && c <= 'z');
29909 }
29910 ArrayH::setArray(arrayptr_a, strA);
29911 set_register(sarg1, (10000)); // used to return 0 if string was empty.
29912 }
29913
29914 void FFScript::do_xlen(const bool v)
29915 {
29916 //not implemented, xlen not found
29917 int32_t arrayptr = (SH::get_arg(sarg2, v));
29918 string str;
29919 ArrayH::getString(arrayptr, str);
29920 }
29921
29922 void FFScript::do_xtoi(const bool v)
29923 {
29924 int32_t arrayptr = (SH::get_arg(sarg2, v));
29925 string str;
29926 ArrayH::getString(arrayptr, str);
29927 double val = zc_xtoi(const_cast<char*>(str.c_str()));
29928 set_register(sarg1, (int32_t)(val) * 10000);
29929 }
29930 void FFScript::do_xtoi2()
29931 {
29932 int32_t arrayptr_a = GET_D(rINDEX);
29933 string strA;
29934 ArrayH::getString(arrayptr_a, strA);
29935 set_register(sarg1, (zc_xtoi(strA.c_str()) * 10000));
29936 }
29937
29938 // Calculates log2 of number.
29939 double FFScript::Log2( double n )
29940 {
29941 // log(n)/log(2) is log2.
29942 return log( (double)n ) / log( (double)2 );
29943 }
29944
29945 //xtoa, convert hex number to hex ascii
29946 14 void FFScript::do_xtoa()
29947 {
29948
29949 14 int32_t arrayptr_a = get_register(sarg1);
29950 14 int32_t number = get_register(sarg2) / 10000;//GET_D(rEXP2)/10000; //why are you not in sarg2?!!
29951
29952
29953
29954 14 bool isneg = false;
29955
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if ( number < 0 )
29956 {
29957 isneg = true;
29958 number *= -1;
29959 }
29960 14 double num = number;
29961
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 int32_t digits = num ? floor(FFCore.LogToBase(num, 16) + 1) : 1;
29962
29963
29964 14 int32_t pos = 0;
29965 14 string strA;
29966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if(number == 0) //Needs to precede str.resize(digits+3) as if the number is <= 0 then this breaks.
29967 {
29968 strA.resize(3);
29969 strA[pos+2] = '0';
29970 if(ArrayH::setArray(arrayptr_a, strA) == SH::_Overflow)
29971 {
29972 Z_scripterrlog("Dest string supplied to 'itoa()' not large enough\n");
29973 set_register(sarg1, 0);
29974 }
29975 else set_register(sarg1, 30000); //returns the pointer to the dest
29976 return;
29977 }
29978 14 int32_t ret = 0;
29979
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 strA.resize(digits+3+(isneg?1:0));
29980 //num = Floor(Abs(num));
29981
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if ( isneg )
29982 {
29983 strA[pos] = '-';
29984 strA[pos+1] = '0';
29985 strA[pos+2] = 'x';
29986 ret = 3;
29987 }
29988 else
29989 {
29990
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 strA[pos] = '0';
29991
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 strA[pos+1] = 'x';
29992 14 ret = 2;
29993 }
29994
29995 14 int32_t alphaoffset = 'A' - 0xA;
29996
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 24 times.
38 for(int32_t i = 0; i < digits; ++i)
29997 {
29998
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 int32_t coeff = ((int32_t)floor((double)(((double)number) / pow((float)0x10, digits - i - 1))) % 0x10);
29999
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 strA[pos + ret + i] = coeff < 0xA ? coeff + '0' : coeff + alphaoffset;
30000 24 }
30001
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
14 if(ArrayH::setArray(arrayptr_a, strA) == SH::_Overflow)
30002 {
30003 scripting_log_error_with_context("Dest string parameter not large enough");
30004 set_register(sarg1, 0);
30005 }
30006
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 else set_register(sarg1, (ret + digits -(isneg?1:0))*10000); //don't count the - sign as a digit
30007
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 }
30008
30009 void FFScript::do_ilen(const bool v)
30010 {
30011 int32_t arrayptr = (SH::get_arg(sarg2, v));
30012 string str;
30013 ArrayH::getString(arrayptr, str);
30014 set_register(sarg1, (FFCore.ilen((char*)str.c_str()) * 10000));
30015 }
30016
30017 //! Note atoi2 (atoi(str, len) can be accompished with str.resize after getString.
30018 void FFScript::do_atoi(const bool v)
30019 {
30020 int32_t arrayptr = (SH::get_arg(sarg2, v));
30021 string str;
30022 ArrayH::getString(arrayptr, str);
30023 set_register(sarg1, (atoi(str.c_str()) * 10000));
30024 }
30025 void FFScript::do_atol(const bool v)
30026 {
30027 int32_t arrayptr = (SH::get_arg(sarg2, v));
30028 string str;
30029 ArrayH::getString(arrayptr, str);
30030 set_register(sarg1, (atoi(str.c_str())));
30031 }
30032
30033 void FFScript::do_strstr()
30034 {
30035
30036 int32_t arrayptr_a = GET_D(rINDEX);
30037 int32_t arrayptr_b = GET_D(rINDEX2);
30038 string strA;
30039 string strB;
30040 ArrayH::getString(arrayptr_a, strA);
30041 ArrayH::getString(arrayptr_b, strB);
30042 if ( strA.size() < 1 )
30043 {
30044 scripting_log_error_with_context("String parameter is too small. Size is: {}", strA.size());
30045 set_register(sarg1,-10000);
30046 return;
30047 }
30048 set_register(sarg1, (strA.find(strB) * 10000));
30049 }
30050
30051 935 void FFScript::do_strcat()
30052 {
30053
30054 935 int32_t arrayptr_a = GET_D(rINDEX);
30055 935 int32_t arrayptr_b = GET_D(rINDEX2);
30056 935 string strA;
30057 935 string strB;
30058
1/2
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
935 ArrayH::getString(arrayptr_a, strA);
30059
1/2
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
935 ArrayH::getString(arrayptr_b, strB);
30060 //char str_c[2048];
30061 //strcpy(str_c, strA.c_str());
30062
1/2
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
935 string strC = strA + strB;
30063
2/4
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 935 times.
935 if(ArrayH::setArray(arrayptr_a, strC) == SH::_Overflow)
30064 {
30065 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30066 set_register(sarg1, 0);
30067 }
30068
1/2
✓ Branch 0 taken 935 times.
✗ Branch 1 not taken.
935 else set_register(sarg1, arrayptr_a); //returns the pointer to the dest
30069 935 }
30070 void FFScript::do_strspn()
30071 {
30072
30073 int32_t arrayptr_a = GET_D(rINDEX);
30074 int32_t arrayptr_b = GET_D(rINDEX2);
30075 string strA;
30076 string strB;
30077 ArrayH::getString(arrayptr_a, strA);
30078 ArrayH::getString(arrayptr_b, strB);
30079 set_register(sarg1, (strspn(strA.c_str(), strB.c_str()) * 10000));
30080 }
30081
30082 void FFScript::do_strcspn()
30083 {
30084
30085 int32_t arrayptr_a = GET_D(rINDEX);
30086 int32_t arrayptr_b = GET_D(rINDEX2);
30087 string strA;
30088 string strB;
30089 ArrayH::getString(arrayptr_a, strA);
30090 ArrayH::getString(arrayptr_b, strB);
30091 set_register(sarg1, (strcspn(strA.c_str(), strB.c_str()) * 10000));
30092 }
30093
30094 void FFScript::do_strchr()
30095 {
30096
30097 int32_t arrayptr_a = GET_D(rINDEX);
30098 char chr_to_find = (GET_D(rINDEX2)/10000);
30099 string strA;
30100 ArrayH::getString(arrayptr_a, strA);
30101 if ( strA.size() < 1 )
30102 {
30103 scripting_log_error_with_context("String parameter is too small. Size is: {}", strA.size());
30104 set_register(sarg1,-10000);
30105 return;
30106 }
30107
30108 set_register(sarg1,strA.find_first_of(chr_to_find)*10000);
30109 }
30110 void FFScript::do_strrchr()
30111 {
30112 int32_t arrayptr_a = GET_D(rINDEX);
30113 char chr_to_find = (GET_D(rINDEX2)/10000);
30114 string strA;
30115 ArrayH::getString(arrayptr_a, strA);
30116 if ( strA.size() < 1 )
30117 {
30118 scripting_log_error_with_context("String parameter is too small. Size is: {}", strA.size());
30119 set_register(sarg1,-10000);
30120 return;
30121 }
30122 set_register(sarg1,strA.find_last_of(chr_to_find)*10000);
30123 }
30124
30125 void FFScript::do_remchr2()
30126 {
30127 //Not implemented, remchr not found
30128 //not part of any standard library
30129 int32_t arrayptr_a = GET_D(rINDEX);
30130 string strA;
30131 ArrayH::getString(arrayptr_a, strA);
30132 }
30133 //Bookmark
30134 void FFScript::do_atoi2()
30135 {
30136 //not implemented; atoi does not take 2 params
30137 int32_t arrayptr_a = GET_D(rINDEX);
30138 string strA;
30139 ArrayH::getString(arrayptr_a, strA);
30140 }
30141 void FFScript::do_ilen2()
30142 {
30143 //not implemented, ilen not found
30144 int32_t arrayptr_a = GET_D(rINDEX);
30145 string strA;
30146 ArrayH::getString(arrayptr_a, strA);
30147 }
30148 void FFScript::do_xlen2()
30149 {
30150 //not implemented, xlen not found
30151 int32_t arrayptr_a = GET_D(rINDEX);
30152 string strA;
30153 ArrayH::getString(arrayptr_a, strA);
30154 }
30155
30156 4797 void FFScript::do_itoa()
30157 {
30158 4797 int32_t arrayptr_a = get_register(sarg1);
30159 4797 int32_t number = get_register(sarg2) / 10000;
30160
30161 char buf[16];
30162 4797 zc_itoa(number, buf, 10);
30163 4797 int32_t ret = ::strlen(buf) * 10000L;
30164
1/2
✓ Branch 0 taken 4797 times.
✗ Branch 1 not taken.
4797 string strA(buf);
30165
30166
2/4
✓ Branch 0 taken 4797 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4797 times.
4797 if(ArrayH::setArray(arrayptr_a, strA) == SH::_Overflow)
30167 {
30168 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30169 set_register(sarg1, -1);
30170 }
30171
1/2
✓ Branch 0 taken 4797 times.
✗ Branch 1 not taken.
4797 else set_register(sarg1, ret); //returns the number of digits used
30172 4797 }
30173
30174 56 void FFScript::do_itoacat()
30175 {
30176 56 int32_t arrayptr_a = get_register(sarg1);
30177 56 int32_t number = get_register(sarg2) / 10000;
30178
30179 56 double num = number;
30180 56 int32_t digits = FFCore.numDigits(number); //int32_t(log10(temp) * 10000.0)
30181 56 int32_t pos = 0;
30182 56 int32_t ret = 0;
30183 56 string strA;
30184 56 string strB;
30185
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 strB.resize(digits);
30186
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 ArrayH::getString(arrayptr_a, strA);
30187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if(num < 0)
30188 {
30189 strB.resize(digits+1);
30190 strB[pos] = '-';
30191 ++ret;
30192 num = -num;
30193 }
30194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 else if(num == 0)
30195 {
30196 strB[pos] = '0';
30197 string strC = strA + strB;
30198 if(ArrayH::setArray(arrayptr_a, strC) == SH::_Overflow)
30199 {
30200 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30201 set_register(sarg1, 0);
30202 }
30203 else set_register(sarg1, arrayptr_a); //returns the pointer to the dest
30204 return;
30205 }
30206
30207
30208
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 84 times.
140 for(int32_t i = 0; i < digits; ++i)
30209
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
84 strB[pos + ret + i] = ((int32_t)floor((double)(num / pow((float)10, digits - i - 1))) % 10) + '0';
30210
30211
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 string strC = strA + strB;
30212
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
56 if(ArrayH::setArray(arrayptr_a, strC) == SH::_Overflow)
30213 {
30214 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30215 set_register(sarg1, 0);
30216 }
30217
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 else set_register(sarg1, arrayptr_a); //returns the pointer to the dest
30218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 }
30219
30220 14127 void FFScript::do_strcpy(const bool a, const bool b)
30221 {
30222 14127 int32_t arrayptr_b = SH::get_arg(sarg1, a);
30223 14127 int32_t arrayptr_a = SH::get_arg(sarg2, b);
30224
30225 14127 string strA;
30226
30227
1/2
✓ Branch 0 taken 14127 times.
✗ Branch 1 not taken.
14127 ArrayH::getString(arrayptr_a, strA);
30228
30229
2/4
✓ Branch 0 taken 14127 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14127 times.
14127 if(ArrayH::setArray(arrayptr_b, strA) == SH::_Overflow)
30230 scripting_log_error_with_context("Dest string parameter is too small. Size is: {}", strA.size());
30231 14127 }
30232 2 void FFScript::do_arraycpy(const bool a, const bool b)
30233 {
30234 2 int32_t arrayptr_dest = SH::get_arg(sarg1, a);
30235 2 int32_t arrayptr_src = SH::get_arg(sarg2, b);
30236 2 ArrayH::copyValues(arrayptr_dest, arrayptr_src);
30237 2 }
30238 17252 void FFScript::do_strlen(const bool v)
30239 {
30240 17252 int32_t arrayptr = (SH::get_arg(sarg2, v));
30241 17252 string str;
30242
1/2
✓ Branch 0 taken 17252 times.
✗ Branch 1 not taken.
17252 ArrayH::getString(arrayptr, str);
30243
1/2
✓ Branch 0 taken 17252 times.
✗ Branch 1 not taken.
17252 set_register(sarg1, (str.length() * 10000));
30244 17252 }
30245
30246 void FFScript::do_strncmp()
30247 {
30248 int32_t arrayptr_a = GET_D(rINDEX);
30249 int32_t arrayptr_b = GET_D(rEXP2);
30250 int32_t len = GET_D(rEXP1)/10000;
30251 string strA;
30252 string strB;
30253 ArrayH::getString(arrayptr_a, strA);
30254 ArrayH::getString(arrayptr_b, strB);
30255 set_register(sarg1, (strncmp(strA.c_str(), strB.c_str(), len) * 10000));
30256 }
30257
30258 void FFScript::do_strnicmp()
30259 {
30260 int32_t arrayptr_a = GET_D(rINDEX);
30261 int32_t arrayptr_b = GET_D(rEXP2);
30262 int32_t len = GET_D(rEXP1)/10000;
30263 string strA;
30264 string strB;
30265 ArrayH::getString(arrayptr_a, strA);
30266 ArrayH::getString(arrayptr_b, strB);
30267 set_register(sarg1, (ustrnicmp(strA.c_str(), strB.c_str(), len) * 10000));
30268 }
30269
30270 /////////////////////
30271 /// MATHS HELPERS ///
30272 /////////////////////
30273
30274 //Returns the log of val to the base 10. Any value <= 0 will return 0.
30275 int32_t FFScript::Log10(double temp)
30276 {
30277 int32_t ret = 0;
30278 if(temp > 0)
30279 ret = int32_t(log10(temp) * 10000.0);
30280 else ret = 0;
30281 return ret;
30282 }
30283
30284 //Returns the number of digits in a given integer.
30285 56 int32_t FFScript::numDigits(int32_t number)
30286 {
30287 56 int32_t digits = 0;
30288
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 56 times.
140 while (number)
30289 {
30290 84 number /= 10;
30291 84 digits++;
30292 }
30293 56 return digits;
30294 }
30295
30296 // Returns the natural logarithm of val (to the base e). Any value <= 0 will return 0.
30297 28 double FFScript::ln(double temp)
30298 {
30299
30300
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if(temp > 0)
30301 28 return (log(temp));
30302 else
30303 {
30304 return 0;
30305 }
30306 28 }
30307
30308 // Returns the logarithm of x to the given base.
30309 14 double FFScript::LogToBase(double x, double base)
30310 {
30311
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if(x <= 0 || base <= 0) return 0;
30312 14 return FFCore.ln(x)/FFCore.ln(base);
30313 14 }
30314
30315 ///----------------------------------------------------------------------------------------------------//
30316 //Debugger and Logging Consoles
30317
30318 template <typename ...Params>
30319 void FFScript::ZScriptConsole(int32_t attributes,const char *format, Params&&... params)
30320 {
30321 //if ( open )
30322 {
30323 zscript_coloured_console.Create("ZQuest Classic Logging Console", 600, 200, NULL, NULL);
30324 zscript_coloured_console.cls(CConsoleLoggerEx::COLOR_BACKGROUND_BLACK);
30325 zscript_coloured_console.gotoxy(0,0);
30326 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30327 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"ZQuest Classic Logging Console\n");
30328
30329 zscript_coloured_console.cprintf( attributes, format, std::forward<Params>(params)...);
30330 }
30331 //else
30332 //{
30333 //close
30334 // zscript_coloured_console.Close();
30335 //}
30336 }
30337
30338 438 void clearConsole()
30339 {
30340 438 zscript_coloured_console.cls(CConsoleLoggerEx::COLOR_BACKGROUND_BLACK);
30341 438 zscript_coloured_console.gotoxy(0,0);
30342
30343 438 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30344 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"\n _____ ____ __ \n");
30345 438 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30346 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK," /__ / / __ \\__ _____ _____/ /_\n");
30347 438 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30348 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK," / / / / / / / / / _ \\/ ___/ __/\n");
30349 438 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30350 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK," / /__/ /_/ / /_/ / __(__ ) /_ \n");
30351 438 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_RED | CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30352 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK," /____/\\___\\_\\__,_/\\___/____/\\__/\n\n");
30353
30354 438 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
30355 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"ZC Console\n");
30356
30357 876 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30358 438 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Running: %s\n", getVersionString());
30359
2/2
✓ Branch 0 taken 324 times.
✓ Branch 1 taken 114 times.
438 if ( FFCore.getQuestHeaderInfo(vZelda) > 0 )
30360 {
30361 114 char const* verstr = QHeader.getVerStr();
30362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if(verstr[0])
30363 {
30364 114 auto vercmp = QHeader.compareVer();
30365 114 auto astatecmp = compare(int32_t(QHeader.getAlphaState()), getAlphaState());
30366 114 auto avercmp = compare(QHeader.getAlphaVer(), 0);
30367 114 auto timecmp = QHeader.compareDate();
30368
4/6
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
114 if(!(vercmp || astatecmp || avercmp))
30369 {
30370
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
21 if(!timecmp || !QHeader.new_version_is_nightly)
30371 42 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30372 21 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Quest Made in this build\n", verstr);
30373 else if(timecmp < 0)
30374 {
30375 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30376 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Quest Made in an earlier nightly of the same build\n", verstr);
30377 }
30378 else
30379 {
30380 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30381 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Quest Made in an LATER nightly of the same build!\n"
30382 "This may be unsafe to play in this version!\n", verstr);
30383 }
30384 21 }
30385 186 else zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE |CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30386 93 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"Quest Made in: %s\n", verstr);
30387 114 }
30388 114 }
30389 438 }
30390 void FFScript::ZScriptConsole(bool open)
30391 {
30392 if ( open )
30393 {
30394 zscript_coloured_console.Create("ZC Console", 600, 200, NULL, NULL);
30395 clearConsole();
30396 console_enabled = 1;
30397 }
30398 else
30399 {
30400 zscript_coloured_console.Close();
30401 console_enabled = 0;
30402 }
30403 zc_set_config("CONSOLE","enabled",console_enabled);
30404 }
30405
30406 ///----------------------------------------------------------------------------------------------------//
30407 //Tracing
30408
30409 12567 void FFScript::do_trace(bool v)
30410 {
30411
5/14
✗ Branch 0 not taken.
✓ Branch 1 taken 12567 times.
✓ Branch 2 taken 12567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12567 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12567 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12567 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
25134 bool should_replay_trace = replay_is_active() && replay_get_meta_bool("script_trace");
30412 // For now, only prevent tracing to allegro log for Web version. Some quests may expect players to
30413 // look in the logs for spoiler/secret stuff.
30414 #ifdef __EMSCRIPTEN__
30415 bool should_trace = console_enabled || should_replay_trace;
30416 if (!should_trace) return;
30417 #endif
30418
30419 12567 int32_t temp = SH::get_arg(sarg1, v);
30420
30421 char tmp[100];
30422
2/2
✓ Branch 0 taken 12561 times.
✓ Branch 1 taken 6 times.
12567 sprintf(tmp, (temp < 0 ? "%06d" : "%05d"), temp);
30423
1/2
✓ Branch 0 taken 12567 times.
✗ Branch 1 not taken.
12567 string s2(tmp);
30424
5/10
✓ Branch 0 taken 12567 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12567 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12567 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 12567 times.
✗ Branch 9 not taken.
12567 s2 = s2.substr(0, s2.size() - 4) + "." + s2.substr(s2.size() - 4, 4) + "\n";
30425
1/2
✓ Branch 0 taken 12567 times.
✗ Branch 1 not taken.
12567 TraceScriptIDs();
30426
1/2
✓ Branch 0 taken 12567 times.
✗ Branch 1 not taken.
12567 al_trace("%s", s2.c_str());
30427
2/2
✓ Branch 0 taken 2290 times.
✓ Branch 1 taken 10277 times.
12567 if (should_replay_trace)
30428
2/4
✓ Branch 0 taken 2290 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2290 times.
✗ Branch 3 not taken.
2290 replay_step_comment("trace: " + s2);
30429
30430
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12567 times.
12567 if ( console_enabled )
30431 {
30432 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30433 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),s2.c_str());
30434 }
30435 12567 }
30436 void FFScript::do_tracel(bool v)
30437 {
30438 int32_t temp = SH::get_arg(sarg1, v);
30439
30440 char tmp[32];
30441 sprintf(tmp, "%d\n", temp);
30442 TraceScriptIDs();
30443 al_trace("%s", tmp);
30444 if (replay_is_active() && replay_get_meta_bool("script_trace"))
30445 replay_step_comment(fmt::format("trace: {}", temp));
30446
30447 if ( console_enabled )
30448 {
30449 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30450 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),tmp);
30451 }
30452 }
30453
30454 void FFScript::do_tracebool(const bool v)
30455 {
30456 int32_t temp = SH::get_arg(sarg1, v);
30457 TraceScriptIDs();
30458 char const* str = temp ? "true\n" : "false\n";
30459 al_trace("%s", str);
30460 if (replay_is_active() && replay_get_meta_bool("script_trace"))
30461 replay_step_comment(fmt::format("trace: {}", (bool)temp));
30462
30463 if ( console_enabled )
30464 {
30465 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30466 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),str);
30467 }
30468 }
30469
30470 35267 void traceStr(string const& str)
30471 {
30472 35267 FFCore.TraceScriptIDs();
30473 35267 safe_al_trace(str);
30474
7/16
✗ Branch 0 not taken.
✓ Branch 1 taken 35267 times.
✓ Branch 2 taken 35267 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 35267 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 35267 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 35267 times.
✓ Branch 10 taken 1645 times.
✓ Branch 11 taken 33622 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
70534 if (replay_is_active() && replay_get_meta_bool("script_trace"))
30475
1/2
✓ Branch 0 taken 33622 times.
✗ Branch 1 not taken.
33622 replay_step_comment("trace: " + str);
30476
30477
1/2
✓ Branch 0 taken 35267 times.
✗ Branch 1 not taken.
35267 if ( console_enabled )
30478 {
30479 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30480 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),str.c_str());
30481 }
30482 35267 }
30483
30484 1383 void FFScript::do_tracestring()
30485 {
30486 1383 int32_t arrayptr = get_register(sarg1);
30487 1383 string str;
30488
1/2
✓ Branch 0 taken 1383 times.
✗ Branch 1 not taken.
1383 ArrayH::getString(arrayptr, str, 512);
30489
1/2
✓ Branch 0 taken 1383 times.
✗ Branch 1 not taken.
1383 str += "\0"; //In the event that the user passed an array w/o NULL, don't crash.
30490
1/2
✓ Branch 0 taken 1383 times.
✗ Branch 1 not taken.
1383 traceStr(str);
30491 1383 }
30492
30493 64346 static int32_t zspr_varg_getter(int32_t,int32_t next_arg)
30494 {
30495 64346 return zs_vargs.at(next_arg);
30496 }
30497 529 static int32_t zspr_stack_getter(int32_t num_args, int32_t next_arg)
30498 {
30499 529 return SH::read_stack(((ri->sp + num_args) - 1) - next_arg);
30500 }
30501
30502 33881 void FFScript::do_printf(const bool v, const bool varg)
30503 {
30504 int32_t num_args, format_arrayptr;
30505
2/2
✓ Branch 0 taken 33594 times.
✓ Branch 1 taken 287 times.
33881 if(varg)
30506 {
30507 33594 num_args = zs_vargs.size();
30508 33594 format_arrayptr = SH::read_stack(ri->sp);
30509 33594 }
30510 else
30511 {
30512 287 num_args = SH::get_arg(sarg1, v) / 10000;
30513 287 format_arrayptr = SH::read_stack(ri->sp + num_args);
30514 }
30515 33881 ArrayManager fmt_am(format_arrayptr);
30516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33881 times.
33881 if(!fmt_am.invalid())
30517 {
30518 33881 string formatstr;
30519
1/2
✓ Branch 0 taken 33881 times.
✗ Branch 1 not taken.
33881 ArrayH::getString(format_arrayptr, formatstr, MAX_ZC_ARRAY_SIZE);
30520
30521
4/6
✓ Branch 0 taken 33594 times.
✓ Branch 1 taken 287 times.
✓ Branch 2 taken 33881 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 33881 times.
33881 traceStr(zs_sprintf(formatstr.c_str(), num_args, varg ? zspr_varg_getter : zspr_stack_getter));
30522 33881 }
30523
2/2
✓ Branch 0 taken 287 times.
✓ Branch 1 taken 33594 times.
33881 if(varg)
30524 33594 zs_vargs.clear();
30525 33881 }
30526
30527 void FFScript::do_printfarr()
30528 {
30529 int32_t format_arrayptr = SH::read_stack(ri->sp + 1),
30530 args_arrayptr = SH::read_stack(ri->sp + 0);
30531 ArrayManager fmt_am(format_arrayptr);
30532 ArrayManager arg_am(args_arrayptr);
30533 if(!(fmt_am.invalid() || arg_am.invalid()))
30534 {
30535 auto num_args = arg_am.size();
30536 string formatstr;
30537 ArrayH::getString(format_arrayptr, formatstr, MAX_ZC_ARRAY_SIZE);
30538
30539 traceStr(zs_sprintf(formatstr.c_str(), num_args,
30540 [&](int32_t,int32_t next_arg)
30541 {
30542 return arg_am.get(next_arg);
30543 }));
30544 }
30545 }
30546
30547 1570475 void FFScript::do_varg_max()
30548 {
30549 1570475 int32_t num_args = zs_vargs.size();
30550 1570475 int32_t val = 0;
30551
1/2
✓ Branch 0 taken 1570475 times.
✗ Branch 1 not taken.
1570475 if (num_args > 0)
30552 1570475 val = zs_vargs.at(0);
30553
2/2
✓ Branch 0 taken 1570475 times.
✓ Branch 1 taken 1570475 times.
3140950 for(auto q = 1; q < num_args; ++q)
30554 {
30555 1570475 int32_t tval = zs_vargs.at(q);
30556
2/2
✓ Branch 0 taken 1245248 times.
✓ Branch 1 taken 325227 times.
1570475 if(tval > val) val = tval;
30557 1570475 }
30558 1570475 zs_vargs.clear();
30559 1570475 SET_D(rEXP1, val);
30560 1570475 }
30561 162607 void FFScript::do_varg_min()
30562 {
30563 162607 int32_t num_args = zs_vargs.size();
30564 162607 int32_t val = 0;
30565
1/2
✓ Branch 0 taken 162607 times.
✗ Branch 1 not taken.
162607 if (num_args > 0)
30566 162607 val = zs_vargs.at(0);
30567
2/2
✓ Branch 0 taken 162607 times.
✓ Branch 1 taken 165281 times.
327888 for(auto q = 1; q < num_args; ++q)
30568 {
30569 165281 int32_t tval = zs_vargs.at(q);
30570
2/2
✓ Branch 0 taken 126870 times.
✓ Branch 1 taken 38411 times.
165281 if(tval < val) val = tval;
30571 165281 }
30572 162607 zs_vargs.clear();
30573 162607 SET_D(rEXP1, val);
30574 162607 }
30575 602347 void FFScript::do_varg_choose()
30576 {
30577 602347 int32_t num_args = zs_vargs.size();
30578 602347 int32_t val = 0;
30579
1/2
✓ Branch 0 taken 602347 times.
✗ Branch 1 not taken.
602347 if(num_args > 0)
30580 {
30581 602347 int32_t choice = zc_rand(num_args-1);
30582 602347 val = zs_vargs.at(choice);
30583 602347 }
30584 602347 zs_vargs.clear();
30585 602347 SET_D(rEXP1, val);
30586 602347 }
30587 30 void FFScript::do_varg_makearray(ScriptType type, const uint32_t UID, script_object_type object_type)
30588 {
30589 30 auto vargs = zs_vargs;
30590 30 zs_vargs.clear();
30591
30592 30 size_t size = vargs.size();
30593 30 SET_D(rEXP1, 0);
30594
30595
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 if (ZScriptVersion::gc_arrays())
30596 {
30597
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 auto* array = script_arrays.create();
30598
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (!array)
30599 return;
30600
30601 30 ZScriptArray &a = array->arr;
30602
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 a.Resize(size);
30603
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 a.setValid(true);
30604
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 a.setObjectType(object_type);
30605
30606
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 30 times.
76 for(size_t j = 0; j < size; ++j)
30607
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 a[j] = vargs[j]; //initialize array
30608
30609 30 SET_D(rEXP1, array->id);
30610
30611 30 return;
30612 }
30613
30614 dword ptrval;
30615 for(ptrval = 1; localRAM[ptrval].Valid(); ptrval++) ;
30616
30617 if(ptrval >= NUM_ZSCRIPT_ARRAYS)
30618 {
30619 Z_scripterrlog("%d local arrays already in use, no more can be allocated\n", NUM_ZSCRIPT_ARRAYS-1);
30620 ptrval = 0;
30621 }
30622 else
30623 {
30624 ZScriptArray &a = localRAM[ptrval];
30625
30626 a.Resize(size);
30627 a.setValid(true);
30628
30629 for(size_t j = 0; j < size; ++j)
30630 a[j] = vargs[j]; //initialize array
30631
30632 arrayOwner[ptrval].clear();
30633 arrayOwner[ptrval].reown(type, UID);
30634 }
30635
30636 SET_D(rEXP1, ptrval*10000);
30637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 }
30638
30639 void FFScript::do_breakpoint()
30640 {
30641 // TODO: implement as `debugger;` statement when VS Code extension exists.
30642 }
30643
30644 22 void FFScript::do_tracenl()
30645 {
30646 22 safe_al_trace("\n");
30647
30648
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if ( console_enabled )
30649 {
30650 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30651 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),"\n");
30652 }
30653 22 }
30654
30655
30656 328103 void FFScript::TraceScriptIDs(bool force_show_context)
30657 {
30658 if(DEVTIMESTAMP)
30659 {
30660 CConsoleLoggerEx console = zscript_coloured_console;
30661 bool cond = console_enabled;
30662
30663 char buf[256] = {0};
30664 //Calculate timestamp
30665 struct tm * tm_struct;
30666 time_t sysRTC;
30667 time (&sysRTC);
30668 tm_struct = localtime (&sysRTC);
30669
30670 sprintf(buf, "[%d:%d:%d] ", tm_struct->tm_hour, tm_struct->tm_min, tm_struct->tm_sec);
30671 //
30672
30673 al_trace("%s", buf);
30674 if ( cond ) {console.safeprint((CConsoleLoggerEx::COLOR_GREEN | CConsoleLoggerEx::COLOR_INTENSITY |
30675 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),buf); }
30676 }
30677
30678
4/4
✓ Branch 0 taken 280269 times.
✓ Branch 1 taken 47834 times.
✓ Branch 2 taken 42651 times.
✓ Branch 3 taken 5183 times.
328103 bool show_context = force_show_context || (get_qr(qr_TRACESCRIPTIDS) || DEVLOGGING);
30679
2/2
✓ Branch 0 taken 5183 times.
✓ Branch 1 taken 322920 times.
328103 if (show_context)
30680 {
30681 322920 CConsoleLoggerEx console = zscript_coloured_console;
30682 322920 bool cond = console_enabled;
30683 322920 char buf[256] = {0};
30684
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 322914 times.
322920 if(script_funcrun)
30685 {
30686
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 sprintf(buf, "Destructor(%d,%s): ", ri->thiskey, destructstr?destructstr->c_str():"UNKNOWN");
30687 6 }
30688
10/18
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 156962 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 30698 times.
✓ Branch 9 taken 53 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 94 times.
✓ Branch 12 taken 3926 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 131120 times.
✗ Branch 17 not taken.
322914 else switch(curScriptType)
30689 {
30690 case ScriptType::Global:
30691 {
30692
2/9
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 131092 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
131120 switch(curScriptNum)
30693 {
30694 case GLOBAL_SCRIPT_INIT:
30695
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 sprintf(buf, "Global Init(%s): ", globalmap[curScriptNum].scriptname.c_str());
30696 28 break;
30697 case GLOBAL_SCRIPT_GAME:
30698
1/2
✓ Branch 0 taken 131092 times.
✗ Branch 1 not taken.
131092 sprintf(buf, "Global Active(%s): ", globalmap[curScriptNum].scriptname.c_str());
30699 131092 break;
30700 case GLOBAL_SCRIPT_END:
30701 sprintf(buf, "Global Exit(%s): ", globalmap[curScriptNum].scriptname.c_str());
30702 break;
30703 case GLOBAL_SCRIPT_ONSAVELOAD:
30704 sprintf(buf, "Global SaveLoad(%s): ", globalmap[curScriptNum].scriptname.c_str());
30705 break;
30706 case GLOBAL_SCRIPT_ONLAUNCH:
30707 sprintf(buf, "Global Launch(%s): ", globalmap[curScriptNum].scriptname.c_str());
30708 break;
30709 case GLOBAL_SCRIPT_ONCONTGAME:
30710 sprintf(buf, "Global ContGame(%s): ", globalmap[curScriptNum].scriptname.c_str());
30711 break;
30712 case GLOBAL_SCRIPT_F6:
30713 sprintf(buf, "Global F6Menu(%s): ", globalmap[curScriptNum].scriptname.c_str());
30714 break;
30715 case GLOBAL_SCRIPT_ONSAVE:
30716 sprintf(buf, "Global Save(%s): ", globalmap[curScriptNum].scriptname.c_str());
30717 break;
30718 }
30719 131120 break;
30720 }
30721
30722 case ScriptType::Hero:
30723 {
30724 switch(curScriptNum)
30725 {
30726 case SCRIPT_HERO_INIT:
30727 sprintf(buf, "Hero Init(%s): ", playermap[curScriptNum-1].scriptname.c_str());
30728 break;
30729 case SCRIPT_HERO_ACTIVE:
30730 sprintf(buf, "Hero Active(%s): ", playermap[curScriptNum-1].scriptname.c_str());
30731 break;
30732 case SCRIPT_HERO_DEATH:
30733 sprintf(buf, "Hero Death(%s): ", playermap[curScriptNum-1].scriptname.c_str());
30734 break;
30735 case SCRIPT_HERO_WIN:
30736 sprintf(buf, "Hero Win(%s): ", playermap[curScriptNum-1].scriptname.c_str());
30737 break;
30738 }
30739 break;
30740 }
30741
30742 case ScriptType::Lwpn:
30743
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 sprintf(buf, "LWeapon(%u, %s): ", curScriptNum,lwpnmap[curScriptNum-1].scriptname.c_str());
30744 48 break;
30745
30746 case ScriptType::Ewpn:
30747
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 sprintf(buf, "EWeapon(%u, %s): ", curScriptNum,ewpnmap[curScriptNum-1].scriptname.c_str());
30748 1 break;
30749
30750 case ScriptType::NPC:
30751 sprintf(buf, "NPC(%u, %s): ", curScriptNum,npcmap[curScriptNum-1].scriptname.c_str());
30752 break;
30753
30754 case ScriptType::FFC:
30755
1/2
✓ Branch 0 taken 156962 times.
✗ Branch 1 not taken.
156962 sprintf(buf, "FFC(%u, %s): ", curScriptNum,ffcmap[curScriptNum-1].scriptname.c_str());
30756 156962 break;
30757
30758 case ScriptType::Item:
30759 sprintf(buf, "Item(%u, %s): ", curScriptNum,itemmap[curScriptNum-1].scriptname.c_str());
30760 break;
30761
30762 case ScriptType::OnMap:
30763 sprintf(buf, "DMapMap(%u, %s): ", curScriptNum,dmapmap[curScriptNum-1].scriptname.c_str());
30764 break;
30765 case ScriptType::ScriptedActiveSubscreen:
30766 sprintf(buf, "DMapASub(%u, %s): ", curScriptNum,dmapmap[curScriptNum-1].scriptname.c_str());
30767 break;
30768 case ScriptType::ScriptedPassiveSubscreen:
30769
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 sprintf(buf, "DMapPSub(%u, %s): ", curScriptNum,dmapmap[curScriptNum-1].scriptname.c_str());
30770 2 break;
30771 case ScriptType::DMap:
30772
1/2
✓ Branch 0 taken 30698 times.
✗ Branch 1 not taken.
30698 sprintf(buf, "DMap(%u, %s): ", curScriptNum,dmapmap[curScriptNum-1].scriptname.c_str());
30773 30698 break;
30774
30775 case ScriptType::ItemSprite:
30776
1/2
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
53 sprintf(buf, "ItemSprite(%u, %s): ", curScriptNum,itemspritemap[curScriptNum-1].scriptname.c_str());
30777 53 break;
30778
30779 case ScriptType::Screen:
30780
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 sprintf(buf, "Screen(%u, %s): ", curScriptNum,screenmap[curScriptNum-1].scriptname.c_str());
30781 10 break;
30782
30783 case ScriptType::Combo:
30784
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 sprintf(buf, "Combo(%u, %s): ", curScriptNum,comboscriptmap[curScriptNum-1].scriptname.c_str());
30785 94 break;
30786
30787 case ScriptType::Generic:
30788
1/2
✓ Branch 0 taken 3926 times.
✗ Branch 1 not taken.
3926 sprintf(buf, "Generic(%u, %s): ", curScriptNum,genericmap[curScriptNum-1].scriptname.c_str());
30789 3926 break;
30790
30791 case ScriptType::GenericFrozen:
30792 sprintf(buf, "GenericFRZ(%u, %s): ", curScriptNum,genericmap[curScriptNum-1].scriptname.c_str());
30793 break;
30794
30795 case ScriptType::EngineSubscreen:
30796 sprintf(buf, "Subscreen(%u, %s): ", curScriptNum,subscreenmap[curScriptNum-1].scriptname.c_str());
30797 break;
30798 }
30799
30800
1/2
✓ Branch 0 taken 322920 times.
✗ Branch 1 not taken.
322920 al_trace("%s", buf);
30801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 322920 times.
322920 if ( cond )
30802 console.safeprint((CConsoleLoggerEx::COLOR_GREEN|CConsoleLoggerEx::COLOR_INTENSITY|
30803 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),buf);
30804 322920 }
30805 328103 }
30806
30807 2 void FFScript::do_cleartrace()
30808 {
30809 2 zc_trace_clear();
30810 2 clearConsole();
30811 2 }
30812
30813 3 string inttobase(word base, int32_t x, word mindigits)
30814 {
30815 static const char coeff[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
30816
30817 3 string s2;
30818
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 word digits = zc_max(mindigits - 1, word(floor(log(double(x)) / log(double(base)))));
30819
30820
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
14 for(int32_t i = digits; i >= 0; i--)
30821 {
30822
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 s2 += coeff[word(floor(x / pow(double(base), i))) % base];
30823 11 }
30824
30825 3 return s2;
30826
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 }
30827
30828 3 void FFScript::do_tracetobase()
30829 {
30830 3 int32_t x = SH::read_stack(ri->sp + 2) / 10000;
30831 3 uint32_t base = vbound(SH::read_stack(ri->sp + 1) / 10000, 2, 36);
30832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 uint32_t mindigits = zc_max(1, SH::read_stack(ri->sp) / 10000);
30833
30834
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 string s2 = x < 0 ? "-": "";
30835
30836
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 switch(base)
30837 {
30838 case 8:
30839 s2 += '0';
30840 break;
30841
30842 case 16:
30843 s2 += "0x";
30844 break;
30845 }
30846
30847
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 s2 += inttobase(base, int32_t(fabs(double(x))), mindigits);
30848
30849
2/3
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
3 switch(base)
30850 {
30851 case 8:
30852 case 10:
30853 case 16:
30854 2 break;
30855
30856 case 2:
30857
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 s2 += 'b';
30858 1 break;
30859
30860 default:
30861 std::stringstream ss;
30862 ss << " (Base " << base << ')';
30863 s2 += ss.str();
30864 break;
30865 }
30866
30867
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 traceStr(s2);
30868
30869
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if ( console_enabled )
30870 {
30871 zscript_coloured_console.safeprint((CConsoleLoggerEx::COLOR_WHITE |
30872 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK),s2.c_str());
30873 }
30874 3 }
30875
30876 int32_t FFScript::getHeroOTile(int32_t index1, int32_t index2)
30877 {
30878 {
30879 herospritetype lst = (herospritetype)index1;
30880 int32_t dir = index2;
30881 int32_t the_ret = 0;
30882 switch(lst)
30883 {
30884 case LSprwalkspr: the_ret = walkspr[dir][0]; break;
30885 case LSprstabspr: the_ret = stabspr[dir][0]; break;
30886 case LSprslashspr: the_ret = slashspr[dir][0]; break;
30887 case LSprrevslashspr: the_ret = revslashspr[dir][0]; break;
30888 case LSprfloatspr: the_ret = floatspr[dir][0]; break;
30889 case LSprswimspr: the_ret = swimspr[dir][0]; break;
30890 case LSprdivespr: the_ret = divespr[dir][0]; break;
30891 case LSprdrownspr: the_ret = drowningspr[dir][0]; break;
30892 case LSprsidedrownspr: the_ret = sidedrowningspr[dir][0]; break;
30893 case LSprlavadrownspr: the_ret = drowning_lavaspr[dir][0]; break;
30894 case LSprsideswimspr: the_ret = sideswimspr[dir][0]; break;
30895 case LSprsideswimslashspr: the_ret = sideswimslashspr[dir][0]; break;
30896 case LSprsideswimstabspr: the_ret = sideswimstabspr[dir][0]; break;
30897 case LSprsideswimpoundspr: the_ret = sideswimpoundspr[dir][0]; break;
30898 case LSprsideswimchargespr: the_ret = sideswimchargespr[dir][0]; break;
30899 case LSprpoundspr: the_ret = poundspr[dir][0]; break;
30900 case LSprjumpspr: the_ret = jumpspr[dir][0]; break;
30901 case LSprchargespr: the_ret = chargespr[dir][0]; break;
30902 case LSprcastingspr: the_ret = castingspr[0]; break;
30903 case LSprsideswimcastingspr: the_ret = sideswimcastingspr[0]; break;
30904 case LSprholdspr1: the_ret = holdspr[0][0][0]; break;
30905 case LSprholdspr2: the_ret = holdspr[0][1][0]; break;
30906 case LSprholdsprw1: the_ret = holdspr[1][0][0]; break;
30907 case LSprholdsprw2: the_ret = holdspr[1][1][0]; break;
30908 case LSprholdsprSw1: the_ret = sideswimholdspr[0][0]; break;
30909 case LSprholdsprSw2: the_ret = sideswimholdspr[1][0]; break;
30910 default: the_ret = 0;
30911 }
30912
30913 return the_ret*10000;
30914 }
30915 }
30916
30917 defWpnSprite FFScript::getDefWeaponSprite(int32_t wpnid)
30918 {
30919 switch(wpnid)
30920 {
30921 case wNone: return ws_0;
30922 case wSword: return ws_0;
30923 case wBeam: return wsBeam;
30924 case wBrang : return wsBrang;
30925 case wBomb: return wsBomb;
30926 case wSBomb: return wsSBomb;
30927 case wLitBomb: return wsBombblast;
30928 case wLitSBomb: return wsBombblast;
30929 case wArrow: return wsArrow;
30930 case wRefArrow: return wsArrow;
30931 case wFire: return wsFire;
30932 case wRefFire: return wsFire;
30933 case wRefFire2: return wsFire;
30934 case wWhistle: return wsUnused45;
30935 case wBait: return wsBait;
30936 case wWand: return wsWandHandle;
30937 case wMagic: return wsMagic;
30938 case wCatching: return wsUnused45;
30939 case wWind: return wsWind;
30940 case wRefMagic: return wsRefMagic;
30941 case wRefFireball: return wsRefFireball;
30942 case wRefRock: return wsRock;
30943 case wHammer: return wsHammer;
30944 case wHookshot: return wsHookshotHead;
30945 case wHSHandle: return wsHookshotHandle;
30946 case wHSChain: return wsHookshotChainH;
30947 case wSSparkle: return wsSilverSparkle;
30948 case wFSparkle: return wsGoldSparkle;
30949 case wSmack: return wsHammerSmack;
30950 case wPhantom: return wsUnused45;
30951 case wCByrna: return wsByrnaCane;
30952 case wRefBeam: return wsRefBeam;
30953 case wStomp: return wsUnused45;
30954 case lwMax: return wsUnused45;
30955 case wScript1:
30956 case wScript2:
30957 case wScript3:
30958 case wScript4:
30959 case wScript5:
30960 case wScript6:
30961 case wScript7:
30962 case wScript8:
30963 case wScript9:
30964 case wScript10: return ws_0;
30965 case wIce: return wsIce; //new
30966 case wFlame: return wsEFire2; //new
30967 //not implemented; t/b/a
30968 case wSound:
30969 case wThrown:
30970 case wPot:
30971 case wLit:
30972 case wBombos:
30973 case wEther:
30974 case wQuake:
30975 case wSword180:
30976 case wSwordLA: return wsUnused45;
30977
30978 case ewFireball: return wsFireball2;
30979 case ewArrow: return wsEArrow;
30980 case ewBrang: return wsBrang;
30981 case ewSword: return wsEBeam;
30982 case ewRock: return wsRock;
30983 case ewMagic: return wsEMagic;
30984 case ewBomb: return wsEBomb;
30985 case ewSBomb: return wsESbomb;
30986 case ewLitBomb: return wsEBombblast;
30987 case ewLitSBomb: return wsESbombblast;
30988 case ewFireTrail: return wsEFiretrail;
30989 case ewFlame: return wsEFire;
30990 case ewWind: return wsEWind;
30991 case ewFlame2: return wsEFire2;
30992 case ewFlame2Trail: return wsEFiretrail2;
30993 case ewIce: return wsIce;
30994 case ewFireball2: return wsFireball2;
30995 default: return wsUnused45;
30996 }
30997 };
30998
30999 598 void FFScript::do_loadlweapon_by_script_uid(const bool v)
31000 {
31001 598 int32_t uid = SH::get_arg(sarg1, v);
31002
1/2
✓ Branch 0 taken 598 times.
✗ Branch 1 not taken.
598 if (ResolveLWeapon_checkSpriteList(uid))
31003 598 ri->lwpnref = uid;
31004 else
31005 {
31006 ri->lwpnref = 0;
31007 }
31008 598 }
31009
31010 void FFScript::do_loadeweapon_by_script_uid(const bool v)
31011 {
31012 int32_t uid = SH::get_arg(sarg1, v);
31013 if (ResolveEWeapon_checkSpriteList(uid))
31014 ri->ewpnref = uid;
31015 else
31016 {
31017 ri->ewpnref = 0;
31018 }
31019 }
31020
31021
31022 12 void FFScript::do_loadnpc_by_script_uid(const bool v)
31023 {
31024 12 int32_t uid = SH::get_arg(sarg1, v);
31025
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (ResolveSprite<enemy>(uid, "enemy"))
31026 12 ri->npcref = uid;
31027 else
31028 {
31029 ri->npcref = 0;
31030 }
31031 12 }
31032
31033 //Combo Scripts
31034
31035 104691 void FFScript::clear_combo_scripts()
31036 {
31037 104691 combo_id_cache.clear();
31038 104691 combo_id_cache.resize(region_num_rpos * 7);
31039 104691 std::fill(combo_id_cache.begin(), combo_id_cache.end(), -1);
31040 104691 FFCore.deallocateAllScriptOwnedOfType(ScriptType::Combo);
31041 104691 FFCore.clear_script_engine_data_of_type(ScriptType::Combo);
31042 104691 }
31043
31044 8607 void FFScript::clear_combo_script(const rpos_handle_t& rpos_handle)
31045 {
31046 8607 int32_t index = get_combopos_ref(rpos_handle);
31047 8607 combo_id_cache[index] = -1;
31048 8607 combopos_modified = index;
31049 8607 clear_script_engine_data(ScriptType::Combo, index);
31050 8607 }
31051
31052 4842536 int32_t FFScript::combo_script_engine(const bool preload, const bool waitdraw)
31053 {
31054 bool enabled[7];
31055
2/2
✓ Branch 0 taken 33897752 times.
✓ Branch 1 taken 4842536 times.
38740288 for (int32_t q = 0; q < 7; ++q)
31056 {
31057 33897752 enabled[q] = get_qr(qr_COMBOSCRIPTS_LAYER_0 + q);
31058 33897752 }
31059
31060 4842536 auto& combo_cache = combo_caches::script;
31061
31062 ///non-scripted effects
31063 3585084168 for_every_rpos([&](const rpos_handle_t& rpos_handle) {
31064
2/2
✓ Branch 0 taken 1440984160 times.
✓ Branch 1 taken 2139257472 times.
3580241632 if (!enabled[rpos_handle.layer])
31065 2139257472 return;
31066
31067 1440984160 int32_t combopos_ref = get_combopos_ref(rpos_handle);
31068 1440984160 word cid = rpos_handle.data();
31069
2/2
✓ Branch 0 taken 1438970088 times.
✓ Branch 1 taken 2014072 times.
1440984160 if(combo_id_cache[combopos_ref] != cid)
31070 {
31071 2014072 combopos_modified = combopos_ref;
31072 2014072 combo_id_cache[combopos_ref] = cid;
31073 2014072 clear_script_engine_data(ScriptType::Combo, combopos_ref);
31074 2014072 }
31075
31076 1440984160 auto script = combo_cache.minis[cid].script;
31077
2/2
✓ Branch 0 taken 1427934204 times.
✓ Branch 1 taken 13049956 times.
1440984160 if (script)
31078 {
31079 13049956 auto& data = get_script_engine_data(ScriptType::Combo, combopos_ref);
31080
2/2
✓ Branch 0 taken 12194395 times.
✓ Branch 1 taken 855561 times.
13049956 if (data.doscript)
31081 {
31082
4/4
✓ Branch 0 taken 423943 times.
✓ Branch 1 taken 431618 times.
✓ Branch 2 taken 419660 times.
✓ Branch 3 taken 4283 times.
855561 if (waitdraw && !data.waitdraw) return; //waitdraw not set
31083
31084 435901 ZScriptVersion::RunScript(ScriptType::Combo, script, combopos_ref);
31085
2/2
✓ Branch 0 taken 431618 times.
✓ Branch 1 taken 4283 times.
435901 if (waitdraw) data.waitdraw = true;
31086 435901 }
31087 12630296 }
31088 3580241632 });
31089
31090 4842536 return 1;
31091 }
31092
31093 823245 int32_t FFScript::Distance(double x1, double y1, double x2, double y2)
31094 {
31095 823245 double x = (x1-x2);
31096 823245 double y = (y1-y2);
31097 823245 double sum = (x*x)+(y*y);
31098 //if(((int32_t)sum) < 0)
31099 //{
31100 // Z_scripterrlog("Distance() attempted to calculate square root of %ld!\n", ((int32_t)sum));
31101 // return -10000;;
31102 //}
31103 823245 sum *= 1000000.0;
31104 823245 double total = sqrt(sum)*10;
31105 823245 return int32_t(total);
31106 }
31107
31108 int32_t FFScript::Distance(double x1, double y1, double x2, double y2, int32_t scale)
31109 {
31110 double x3 = x1+(x2-x1)/scale;
31111 double y3 = y1+(y2-y1)/scale;
31112 //double sum = (x*x)+(y*y);
31113 //if(((int32_t)sum) < 0)
31114 //{
31115 // Z_scripterrlog("Distance() attempted to calculate square root of %ld!\n", ((int32_t)sum));
31116 // return -10000;
31117 //}
31118 //sum *= 1000000.0;
31119 //double total = sqrt(sum)*10;
31120 //return int32_t(total*scale);
31121 return (FFCore.Distance(x1, y1, x3, y3)*scale);
31122 }
31123
31124 int32_t FFScript::LongDistance(double x1, double y1, double x2, double y2)
31125 {
31126 double x = (x1-x2);
31127 double y = (y1-y2);
31128 double sum = (x*x)+(y*y);
31129 //if(((int32_t)sum) < 0)
31130 //{
31131 // Z_scripterrlog("Distance() attempted to calculate square root of %ld!\n", ((int32_t)sum));
31132 // return -10000;;
31133 //}
31134 double total = sqrt(sum);
31135 return int32_t(total);
31136 }
31137
31138 int32_t FFScript::LongDistance(double x1, double y1, double x2, double y2, int32_t scale)
31139 {
31140 double x3 = x1+(x2-x1)/scale;
31141 double y3 = y1+(y2-y1)/scale;
31142 //double sum = (x*x)+(y*y);
31143 //if(((int32_t)sum) < 0)
31144 //{
31145 // Z_scripterrlog("Distance() attempted to calculate square root of %ld!\n", ((int32_t)sum));
31146 // return -10000;
31147 //}
31148 //sum *= 1000000.0;
31149 //double total = sqrt(sum)*10;
31150 //return int32_t(total*scale);
31151 return (FFCore.LongDistance(x1, y1, x3, y3)*scale);
31152 }
31153
31154 419385179 bool command_is_wait(int command)
31155 {
31156
2/2
✓ Branch 0 taken 419197704 times.
✓ Branch 1 taken 187475 times.
419385179 switch (command)
31157 {
31158 case WAITFRAME:
31159 case WAITDRAW:
31160 case WAITTO:
31161 case WAITEVENT:
31162 case WAITFRAMESR:
31163 187475 return true;
31164 }
31165 419197704 return false;
31166 419385179 }
31167
31168 297906141 bool command_is_goto(int command)
31169 {
31170 // GOTOR/return ops left out on purpose.
31171
2/2
✓ Branch 0 taken 276675262 times.
✓ Branch 1 taken 21230879 times.
297906141 switch (command)
31172 {
31173 case GOTO:
31174 case GOTOCMP:
31175 case GOTOLESS:
31176 case GOTOMORE:
31177 case GOTOTRUE:
31178 case GOTOFALSE:
31179 21230879 return true;
31180 }
31181 276675262 return false;
31182 297906141 }
31183
31184 100009740 bool command_uses_comparison_result(int command)
31185 {
31186
2/2
✓ Branch 0 taken 95605018 times.
✓ Branch 1 taken 4404722 times.
100009740 switch (command)
31187 {
31188 case GOTOTRUE:
31189 case GOTOFALSE:
31190 case GOTOMORE:
31191 case GOTOLESS:
31192 case GOTOCMP:
31193 case SETCMP:
31194 case SETTRUE:
31195 case SETTRUEI:
31196 case SETFALSE:
31197 case SETFALSEI:
31198 case SETMOREI:
31199 case SETLESSI:
31200 case SETMORE:
31201 case SETLESS:
31202 case STACKWRITEATVV_IF:
31203 4404722 return true;
31204 }
31205 95605018 return false;
31206 100009740 }
31207
31208 200364398 bool command_writes_comparison_result(int command)
31209 {
31210
2/2
✓ Branch 0 taken 192177675 times.
✓ Branch 1 taken 8186723 times.
200364398 switch (command)
31211 {
31212 case SETCMP:
31213 case SETTRUE:
31214 case SETTRUEI:
31215 case SETFALSE:
31216 case SETFALSEI:
31217 case SETMOREI:
31218 case SETLESSI:
31219 case SETMORE:
31220 case SETLESS:
31221 8186723 return true;
31222 }
31223 192177675 return false;
31224 200364398 }
31225
31226 13411943 int command_to_cmp(int command, int arg)
31227 {
31228
12/14
✓ Branch 0 taken 2288455 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3238483 times.
✓ Branch 3 taken 5658 times.
✓ Branch 4 taken 81771 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3086401 times.
✓ Branch 7 taken 1407473 times.
✓ Branch 8 taken 1824600 times.
✓ Branch 9 taken 766480 times.
✓ Branch 10 taken 431373 times.
✓ Branch 11 taken 52695 times.
✓ Branch 12 taken 191023 times.
✓ Branch 13 taken 37531 times.
13411943 switch (command)
31229 {
31230 case SETCMP:
31231 case GOTOCMP:
31232 2288455 return arg;
31233
31234 case GOTOTRUE:
31235 3238483 return CMP_EQ;
31236 case GOTOFALSE:
31237 5658 return CMP_NE;
31238 case GOTOMORE:
31239 81771 return CMP_GE;
31240 case GOTOLESS:
31241 return get_qr(qr_GOTOLESSNOTEQUAL) ? CMP_LE : CMP_LT;
31242
31243 case SETTRUE:
31244 3086401 return CMP_EQ;
31245 case SETFALSE:
31246 1407473 return CMP_NE;
31247 case SETMORE:
31248 1824600 return CMP_GE;
31249 case SETLESS:
31250 766480 return CMP_LE;
31251
31252 case SETTRUEI:
31253 431373 return CMP_SETI|CMP_EQ;
31254 case SETFALSEI:
31255 52695 return CMP_SETI|CMP_NE;
31256 case SETMOREI:
31257 191023 return CMP_SETI|CMP_GE;
31258 case SETLESSI:
31259 37531 return CMP_SETI|CMP_LE;
31260 }
31261
31262 ASSERT(false);
31263 return 0;
31264 13411943 }
31265
31266 1426552 bool command_could_return_not_ok(int command)
31267 {
31268
2/2
✓ Branch 0 taken 1423852 times.
✓ Branch 1 taken 2700 times.
1426552 switch (command)
31269 {
31270 case 0xFFFF:
31271 case EWPNDEL:
31272 case GAMECONTINUE:
31273 case GAMEEND:
31274 case GAMEEXIT:
31275 case GAMERELOAD:
31276 case GAMESAVECONTINUE:
31277 case GAMESAVEQUIT:
31278 case ITEMDEL:
31279 case LWPNDEL:
31280 case NPCKICKBUCKET:
31281 2700 return true;
31282 }
31283 1423852 return false;
31284 1426552 }
31285
31286 172063789 bool command_is_pure(int command)
31287 {
31288
2/2
✓ Branch 0 taken 118156917 times.
✓ Branch 1 taken 53906872 times.
172063789 switch (command)
31289 {
31290 case ABS:
31291 case ADDR:
31292 case ADDV:
31293 case ANDR:
31294 case ANDR32:
31295 case ANDV:
31296 case ANDV32:
31297 case ARCCOSR:
31298 case ARCSINR:
31299 case BITNOT:
31300 case BITNOT32:
31301 case CASTBOOLF:
31302 case CEILING:
31303 case COMPAREV2:
31304 case COSR:
31305 case COSV:
31306 case DIVR:
31307 case DIVV:
31308 case DIVV2:
31309 case FACTORIAL:
31310 case FLOOR:
31311 case IPOWERR:
31312 case IPOWERV:
31313 case ISALLOCATEDBITMAP:
31314 case LOAD:
31315 case LOADD:
31316 case LOADI:
31317 case LOG10:
31318 case LOGE:
31319 case LPOWERR:
31320 case LPOWERV:
31321 case LPOWERV2:
31322 case LSHIFTR:
31323 case LSHIFTR32:
31324 case LSHIFTV:
31325 case LSHIFTV32:
31326 case MAXR:
31327 case MAXV:
31328 case MINR:
31329 case MINV:
31330 case MODR:
31331 case MODV:
31332 case MODV2:
31333 case MULTR:
31334 case MULTV:
31335 case NANDR:
31336 case NANDV:
31337 case NORR:
31338 case NORV:
31339 case NOT:
31340 case ORR:
31341 case ORR32:
31342 case ORV:
31343 case ORV32:
31344 case PEEK:
31345 case PEEKATV:
31346 case POWERR:
31347 case POWERV:
31348 case POWERV2:
31349 case ROUND:
31350 case ROUNDAWAY:
31351 case RSHIFTR:
31352 case RSHIFTR32:
31353 case RSHIFTV:
31354 case RSHIFTV32:
31355 case SETCMP:
31356 case SETFALSE:
31357 case SETFALSEI:
31358 case SETLESS:
31359 case SETLESSI:
31360 case SETMORE:
31361 case SETMOREI:
31362 case SETR:
31363 case SETTRUE:
31364 case SETTRUEI:
31365 case SETV:
31366 case SINR:
31367 case SINV:
31368 case SQROOTR:
31369 case SQROOTV:
31370 case SUBR:
31371 case SUBV:
31372 case SUBV2:
31373 case TANR:
31374 case TANV:
31375 case TOBYTE:
31376 case TOINTEGER:
31377 case TOSHORT:
31378 case TOSIGNEDBYTE:
31379 case TOWORD:
31380 case TRUNCATE:
31381 case XNORR:
31382 case XNORV:
31383 case XORR:
31384 case XORR32:
31385 case XORV:
31386 case XORV32:
31387 53906872 return true;
31388 }
31389
31390 118156917 return false;
31391 172063789 }
31392
31393 1441005121 int32_t get_combopos_ref(const rpos_handle_t& rpos_handle)
31394 {
31395 1441005121 return rpos_handle.layer * region_num_rpos + (int)rpos_handle.rpos;
31396 }
31397
31398 int32_t get_combopos_ref(rpos_t rpos, int32_t layer)
31399 {
31400 return layer * region_num_rpos + (int)rpos;
31401 }
31402
31403 1381722 rpos_t combopos_ref_to_rpos(int32_t combopos_ref)
31404 {
31405 1381722 return (rpos_t)(combopos_ref % region_num_rpos);
31406 }
31407
31408 455086 int32_t combopos_ref_to_layer(int32_t combopos_ref)
31409 {
31410 455086 return combopos_ref / region_num_rpos;
31411 }
31412
31413 ScriptEngineData& get_ffc_script_engine_data(int index)
31414 {
31415 return get_script_engine_data(ScriptType::FFC, index);
31416 }
31417
31418 1648949 ScriptEngineData& get_item_script_engine_data(int index)
31419 {
31420 1648949 return get_script_engine_data(ScriptType::Item, index);
31421 }
31422
31423 #ifdef DEBUG_REGISTER_DEPS
31424
31425 static std::array<int, 8> debug_deps_cur_regs;
31426 static int debug_ref;
31427
31428 #define REG_R ((int)ARGTY::READ_REG)
31429 #define REG_W ((int)ARGTY::WRITE_REG)
31430
31431 int debug_get_d(int r)
31432 {
31433 CHECK(!(debug_deps_cur_regs[r] & REG_W));
31434 debug_deps_cur_regs[r] |= REG_R;
31435 return ri->d[r];
31436 }
31437
31438 int debug_set_d(int r, int v)
31439 {
31440 debug_deps_cur_regs[r] |= REG_W;
31441 return ri->d[r];
31442 }
31443
31444 int debug_get_ref(std::string reg_name)
31445 {
31446 util::upperstr(reg_name);
31447 util::replstr(reg_name, "REF", "");
31448 reg_name = "REF" + reg_name;
31449 int r = get_script_variable(reg_name).value();
31450 return debug_get_ref(r);
31451 }
31452
31453 int debug_get_ref(int r)
31454 {
31455 if (r == debug_ref) return get_ref(r);
31456
31457 CHECK(!debug_ref);
31458 debug_ref = r;
31459 return get_ref(r);
31460 }
31461
31462 static const char* get_d_reg_name(int r)
31463 {
31464 if (r == 0) return "rINDEX";
31465 if (r == 1) return "rINDEX2";
31466 if (r == 2) return "rEXP1";
31467 if (r == 3) return "rEXP2";
31468 if (r == 4) return "rSFRAME";
31469 if (r == 5) return "rNUL";
31470 if (r == 6) return "rSFTEMP";
31471 if (r == 7) return "rWHAT_NO_7";
31472 NOTREACHED();
31473 }
31474
31475 static void reset_test_ri(refInfo* ri)
31476 {
31477 *ri = {};
31478 ri->sp = MAX_STACK_SIZE - 100;
31479 ri->screenref = cur_screen;
31480 ri->msgdataref = -1;
31481 }
31482
31483 void print_d_register_deps()
31484 {
31485 refInfo testRi;
31486 ri = &testRi;
31487 std::array<int32_t, MAX_STACK_SIZE> testStack{};
31488 testStack.fill(10000);
31489 stack = (int32_t (*)[MAX_STACK_SIZE])testStack.data();
31490
31491 // value -> case labels
31492 std::map<std::string, std::vector<std::string>> value_to_labels;
31493 std::map<std::string, std::vector<std::string>> value_to_labels2;
31494
31495 for (int i = 0; i < NUMVARIABLES; i++)
31496 {
31497 auto [sv, _] = get_script_variable(i);
31498 if (!sv) continue;
31499
31500 reset_test_ri(&testRi);
31501 for (int j = 0; j < 8; j++) ri->d[j] = i == 4891 ? 10000 : 0;
31502
31503 debug_deps_cur_regs = {};
31504 debug_ref = 0;
31505 get_register(i);
31506
31507 bool any = false;
31508 for (int j = 0; j < 8; j++)
31509 {
31510 if (debug_deps_cur_regs[j])
31511 any = true;
31512 }
31513
31514 if (any)
31515 {
31516 std::vector<std::string> reg_names;
31517 for (int j = 0; j < 8; j++)
31518 {
31519 CHECK(!(debug_deps_cur_regs[j] & REG_W));
31520 if (!debug_deps_cur_regs[j])
31521 continue;
31522
31523 reg_names.push_back(get_d_reg_name(j));
31524 }
31525
31526 std::string value = fmt::format("{{{}}}", fmt::join(reg_names, ", "));
31527 if (auto* labels = util::find(value_to_labels, value))
31528 labels->push_back(sv->name);
31529 else
31530 value_to_labels[value] = {sv->name};
31531 }
31532
31533 if (debug_ref)
31534 {
31535 std::string value = get_script_variable(debug_ref).first->name;
31536 if (auto* labels = util::find(value_to_labels2, value))
31537 labels->push_back(sv->name);
31538 else
31539 value_to_labels2[value] = {sv->name};
31540 }
31541 }
31542
31543 fmt::println("static std::vector<int> _get_register_dependencies(int reg)");
31544 fmt::println("{{");
31545 fmt::println("\tswitch (reg)");
31546 fmt::println("\t{{");
31547
31548 for (auto& [value, labels] : value_to_labels | std::views::reverse)
31549 {
31550 std::sort(labels.begin(), labels.end());
31551 for (auto& label : labels)
31552 fmt::println("\t\tcase {}:", label);
31553 fmt::println("\t\t{{");
31554 fmt::println("\t\t\treturn {};", value);
31555 fmt::println("\t\t}}");
31556 fmt::println("");
31557 }
31558 value_to_labels.clear();
31559
31560 fmt::println("\t}}");
31561 fmt::println("");
31562 fmt::println("\treturn {{}};");
31563 fmt::println("}}");
31564
31565 fmt::println("std::optional<int> get_register_ref_dependency(int reg)");
31566 fmt::println("{{");
31567 fmt::println("\tswitch (reg)");
31568 fmt::println("\t{{");
31569
31570 for (auto& [value, labels] : value_to_labels2)
31571 {
31572 std::sort(labels.begin(), labels.end());
31573 for (auto& label : labels)
31574 fmt::println("\t\tcase {}:", label);
31575 fmt::println("\t\t\treturn {};", value);
31576 fmt::println("");
31577 }
31578
31579 fmt::println("\t}}");
31580 fmt::println("");
31581 fmt::println("\treturn {{}};");
31582 fmt::println("}}");
31583
31584 curscript = new script_data(ScriptType::None, 0);
31585 curscript->zasm_script = std::make_shared<zasm_script>();
31586
31587 JittedScriptInstance j_instance{};
31588 j_instance.script = curscript;
31589
31590 for (int i = 0; i < NUMCOMMANDS; i++)
31591 {
31592 if (command_is_goto(i) || command_is_wait(i) || command_uses_comparison_result(i) || command_writes_comparison_result(i))
31593 continue;
31594
31595 switch (i)
31596 {
31597 case CALLFUNC:
31598 case CLOSEWIPE:
31599 case CLOSEWIPESHAPE:
31600 case DEALLOCATEMEMR:
31601 case FXWAVYR:
31602 case FXWAVYV:
31603 case FXZAPR:
31604 case FXZAPV:
31605 case GAMECONTINUE:
31606 case GAMEEND:
31607 case GAMEEXIT:
31608 case GAMERELOAD:
31609 case GAMESAVECONTINUE:
31610 case GAMESAVEQUIT:
31611 case GOTOR:
31612 case LOAD_INTERNAL_ARRAY_REF:
31613 case LOAD_INTERNAL_ARRAY:
31614 case MARK_TYPE_REG:
31615 case OBJ_OWN_ARRAY:
31616 case OBJ_OWN_BITMAP:
31617 case OBJ_OWN_DIR:
31618 case OBJ_OWN_FILE:
31619 case OBJ_OWN_PALDATA:
31620 case OBJ_OWN_RNG:
31621 case OBJ_OWN_STACK:
31622 case OPENWIPE:
31623 case OPENWIPESHAPE:
31624 case POP:
31625 case POPARGS:
31626 case PUSHARGSR:
31627 case PUSHARGSV:
31628 case PUSHR:
31629 case PUSHV:
31630 case QUIT:
31631 case RETURN:
31632 case RETURNFUNC:
31633 case SAVE:
31634 case SAVEQUITSCREEN:
31635 case SAVESCREEN:
31636 case SET_OBJECT:
31637 case SHOWF6SCREEN:
31638 case STARTDESTRUCTOR:
31639 case WAVYIN:
31640 case WAVYOUT:
31641 case ZAPIN:
31642 case ZAPOUT:
31643 case ZCLASS_CONSTRUCT:
31644 case ZCLASS_MARK_TYPE:
31645 continue;
31646 }
31647
31648 if (!get_script_command(i))
31649 continue;
31650
31651 curscript->zasm_script->zasm.push_back({(word)i});
31652 }
31653
31654 curscript->zasm_script->zasm.push_back({NOP});
31655 curscript->zasm_script->size = curscript->end_pc = curscript->zasm_script->zasm.size();
31656
31657 for (int i = 0; i < curscript->zasm_script->size; i++)
31658 {
31659 reset_test_ri(&testRi);
31660
31661 debug_deps_cur_regs = {};
31662 debug_ref = 0;
31663
31664 int command = curscript->zasm_script->zasm[i].command;
31665 auto sc = get_script_command(command);
31666
31667 switch (command)
31668 {
31669 case REF_DEC:
31670 case REF_INC:
31671 {
31672 debug_deps_cur_regs[rSFRAME] = REG_R;
31673 break;
31674 }
31675
31676 default:
31677 {
31678 run_script_jit_one(&j_instance, i, MAX_STACK_SIZE - 100);
31679 }
31680 }
31681
31682 bool any = false;
31683 for (int j = 0; j < 8; j++)
31684 {
31685 if (debug_deps_cur_regs[j])
31686 any = true;
31687 if (debug_deps_cur_regs[j] & REG_W)
31688 CHECK(!command_is_pure(command));
31689 }
31690 if (!any)
31691 continue;
31692
31693 std::vector<std::string> parts;
31694 for (int j = 0; j < 8; j++)
31695 {
31696 if (!debug_deps_cur_regs[j])
31697 continue;
31698
31699 bool r = debug_deps_cur_regs[j] & REG_R;
31700 bool w = debug_deps_cur_regs[j] & REG_W;
31701 std::string value;
31702 if (r && w) value = "REG_RW";
31703 else if (r) value = "REG_R";
31704 else if (w) value = "REG_W";
31705
31706 parts.push_back(fmt::format("{{{}, {}}}", get_d_reg_name(j), value));
31707 }
31708
31709 std::string value = fmt::format("{{{}}}", fmt::join(parts, ", "));
31710 if (auto* labels = util::find(value_to_labels, value))
31711 labels->push_back(sc->name);
31712 else
31713 value_to_labels[value] = {sc->name};
31714 }
31715
31716 value_to_labels["{{CLASS_THISKEY, REG_W}}"] = {"ZCLASS_MARK_TYPE"};
31717 value_to_labels["{{rEXP1, REG_R}, {CLASS_THISKEY, REG_W}}"] = {"ZCLASS_CONSTRUCT"};
31718 value_to_labels["{{SP, REG_RW}, {SP2, REG_RW}}"] = {"POP", "POPARGS", "PUSHARGSR", "PUSHARGSV", "PUSHR", "PUSHV"};
31719
31720 fmt::println("std::initializer_list<CommandDependency> get_command_implicit_dependencies(int command)");
31721 fmt::println("{{");
31722 fmt::println("\ttypedef std::initializer_list<CommandDependency> T;");
31723 fmt::println("");
31724 fmt::println("\tswitch (command)");
31725 fmt::println("\t{{");
31726
31727 for (auto& [value, labels] : value_to_labels | std::views::reverse)
31728 {
31729 std::sort(labels.begin(), labels.end());
31730 for (auto& label : labels)
31731 fmt::println("\t\tcase {}:", label);
31732 fmt::println("\t\t{{");
31733 fmt::println("\t\t\tstatic T r = {};", value);
31734 fmt::println("\t\t\treturn r;");
31735 fmt::println("\t\t}}");
31736 fmt::println("");
31737 }
31738 value_to_labels.clear();
31739
31740 fmt::println("\t}}");
31741 fmt::println("");
31742 fmt::println("\treturn {{}};");
31743 fmt::println("}}");
31744
31745 exit(0);
31746 }
31747
31748 #endif
31749